initgraph, whole lot of refactor

This commit is contained in:
2026-10-12 15:36:48 +02:00
parent 41cc7fea77
commit eabce70866
79 changed files with 3700 additions and 302 deletions
+16
View File
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: ISC
#pragma once
typedef __builtin_va_list va_list;
#undef va_start
#define va_start(v, ...) __builtin_va_start(v, 0)
#undef va_end
#define va_end(v) __builtin_va_end(v)
#undef va_arg
#define va_arg(v, l) __builtin_va_arg(v, l)
#undef va_copy
#define va_copy(d, s) __builtin_va_copy(d, s)
+163
View File
@@ -0,0 +1,163 @@
// SPDX-License-Identifier: ISC
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST,
} memory_order;
#define atomic_thread_fence(order) __atomic_thread_fence(order)
#define atomic_signal_fence(order) __atomic_signal_fence(order)
#ifdef __clang__
#define atomic_init(obj, value) __c11_atomic_init(obj, value)
#define atomic_store_explicit(obj, val, order) __c11_atomic_store(obj, val, order)
#define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order)
#define atomic_exchange_explicit(obj, val, order) __c11_atomic_exchange(obj, val, order)
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
__c11_atomic_compare_exchange_strong(obj, expected, desired, succ, fail)
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
__c11_atomic_compare_exchange_weak(obj, expected, desired, succ, fail)
#define atomic_fetch_add_explicit(obj, arg, order) __c11_atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub_explicit(obj, arg, order) __c11_atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_or_explicit(obj, arg, order) __c11_atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor_explicit(obj, arg, order) __c11_atomic_fetch_xor(obj, arg, order)
#define atomic_fetch_and_explicit(obj, arg, order) __c11_atomic_fetch_and(obj, arg, order)
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
#else /* GCC */
#define atomic_init(obj, value) \
do { \
*(obj) = (value); \
} while (0)
#define atomic_store_explicit(obj, val, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __av = (val); \
__atomic_store(__ao, &__av, order); \
})
#define atomic_load_explicit(obj, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __ar; \
__atomic_load(__ao, &__ar, order); \
__ar; \
})
#define atomic_exchange_explicit(obj, val, order) \
({ \
auto __ao = (obj); \
typeof(*__ao) __av = (val); \
typeof(*__ao) __ar; \
__atomic_exchange(__ao, &__av, &__ar, order); \
__ar; \
})
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
({ \
auto __ao = (obj); \
auto __ae = (expected); \
typeof(*__ao) __ad = (desired); \
__atomic_compare_exchange(__ao, __ae, &__ad, 0, succ, fail); \
})
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
({ \
auto __ao = (obj); \
auto __ae = (expected); \
typeof(*__ao) __ad = (desired); \
__atomic_compare_exchange(__ao, __ae, &__ad, 1, succ, fail); \
})
#define atomic_fetch_add_explicit(obj, arg, order) __atomic_fetch_add(obj, arg, order)
#define atomic_fetch_sub_explicit(obj, arg, order) __atomic_fetch_sub(obj, arg, order)
#define atomic_fetch_or_explicit(obj, arg, order) __atomic_fetch_or(obj, arg, order)
#define atomic_fetch_xor_explicit(obj, arg, order) __atomic_fetch_xor(obj, arg, order)
#define atomic_fetch_and_explicit(obj, arg, order) __atomic_fetch_and(obj, arg, order)
#define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof(*(obj)), (obj))
#endif
#define atomic_store(obj, val) atomic_store_explicit(obj, val, memory_order_seq_cst)
#define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst)
#define atomic_exchange(obj, val) atomic_exchange_explicit(obj, val, memory_order_seq_cst)
#define atomic_compare_exchange_strong(obj, expected, desired) \
atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_compare_exchange_weak(obj, expected, desired) \
atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_fetch_add(obj, arg) atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_sub(obj, arg) atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_or(obj, arg) atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_xor(obj, arg) atomic_fetch_xor_explicit(obj, arg, memory_order_seq_cst)
#define atomic_fetch_and(obj, arg) atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst)
// atomic_flag
typedef struct atomic_flag {
_Atomic(bool) __val;
} atomic_flag;
#define ATOMIC_FLAG_INIT {0}
#define atomic_flag_test_and_set_explicit(obj, order) atomic_exchange_explicit(&(obj)->__val, 1, order)
#define atomic_flag_test_and_set(obj) atomic_flag_test_and_set_explicit(obj, memory_order_seq_cst)
#define atomic_flag_clear_explicit(obj, order) atomic_store_explicit(&(obj)->__val, 0, order)
#define atomic_flag_clear(obj) atomic_flag_clear_explicit(obj, memory_order_seq_cst)
typedef _Atomic(bool) atomic_bool;
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
typedef _Atomic(__CHAR16_TYPE__) atomic_char16_t;
typedef _Atomic(__CHAR32_TYPE__) atomic_char32_t;
typedef _Atomic(__WCHAR_TYPE__) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
+6
View File
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: ISC
#pragma once
#define ckd_add(result, a, b) __builtin_add_overflow(a, b, result)
#define ckd_sub(result, a, b) __builtin_sub_overflow(a, b, result)
#define ckd_mul(result, a, b) __builtin_mul_overflow(a, b, result)
+14
View File
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: ISC
#pragma once
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __WCHAR_TYPE__ wchar_t;
typedef typeof(nullptr) nullptr_t;
#undef offsetof
#define offsetof(s, m) __builtin_offsetof(s, m)
#undef unreachable
#define unreachable() __builtin_unreachable()
+354
View File
@@ -0,0 +1,354 @@
// SPDX-License-Identifier: ISC
#pragma once
#ifdef __UINT8_TYPE__
typedef __UINT8_TYPE__ uint8_t;
#endif
#ifdef __UINT16_TYPE__
typedef __UINT16_TYPE__ uint16_t;
#endif
#ifdef __UINT32_TYPE__
typedef __UINT32_TYPE__ uint32_t;
#endif
#ifdef __UINT64_TYPE__
typedef __UINT64_TYPE__ uint64_t;
#endif
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#ifdef __INT8_TYPE__
typedef __INT8_TYPE__ int8_t;
#endif
#ifdef __INT16_TYPE__
typedef __INT16_TYPE__ int16_t;
#endif
#ifdef __INT32_TYPE__
typedef __INT32_TYPE__ int32_t;
#endif
#ifdef __INT64_TYPE__
typedef __INT64_TYPE__ int64_t;
#endif
typedef __INT_LEAST8_TYPE__ int_least8_t;
typedef __INT_LEAST16_TYPE__ int_least16_t;
typedef __INT_LEAST32_TYPE__ int_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
#ifdef __UINTPTR_TYPE__
typedef __UINTPTR_TYPE__ uintptr_t;
#endif
#ifdef __INTPTR_TYPE__
typedef __INTPTR_TYPE__ intptr_t;
#endif
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __INTMAX_TYPE__ intmax_t;
// Clang and GCC have different mechanisms for INT32_C and friends.
#ifdef __clang__
#ifndef __FREESTANDING_C_HDRS_C_JOIN
#define __FREESTANDING_C_HDRS_C_EXPAND_JOIN(x, suffix) x##suffix
#define __FREESTANDING_C_HDRS_C_JOIN(x, suffix) __FREESTANDING_C_HDRS_C_EXPAND_JOIN(x, suffix)
#endif
#undef INT8_C
#define INT8_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __INT8_C_SUFFIX__)
#undef INT16_C
#define INT16_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __INT16_C_SUFFIX__)
#undef INT32_C
#define INT32_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __INT32_C_SUFFIX__)
#undef INT64_C
#define INT64_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __INT64_C_SUFFIX__)
#undef UINT8_C
#define UINT8_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __UINT8_C_SUFFIX__)
#undef UINT16_C
#define UINT16_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __UINT16_C_SUFFIX__)
#undef UINT32_C
#define UINT32_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __UINT32_C_SUFFIX__)
#undef UINT64_C
#define UINT64_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __UINT64_C_SUFFIX__)
#undef INTMAX_C
#define INTMAX_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __INTMAX_C_SUFFIX__)
#undef UINTMAX_C
#define UINTMAX_C(x) __FREESTANDING_C_HDRS_C_JOIN(x, __UINTMAX_C_SUFFIX__)
#else
#undef INT8_C
#define INT8_C(x) __INT8_C(x)
#undef INT16_C
#define INT16_C(x) __INT16_C(x)
#undef INT32_C
#define INT32_C(x) __INT32_C(x)
#undef INT64_C
#define INT64_C(x) __INT64_C(x)
#undef UINT8_C
#define UINT8_C(x) __UINT8_C(x)
#undef UINT16_C
#define UINT16_C(x) __UINT16_C(x)
#undef UINT32_C
#define UINT32_C(x) __UINT32_C(x)
#undef UINT64_C
#define UINT64_C(x) __UINT64_C(x)
#undef INTMAX_C
#define INTMAX_C(x) __INTMAX_C(x)
#undef UINTMAX_C
#define UINTMAX_C(x) __UINTMAX_C(x)
#endif
#ifdef __UINT8_MAX__
#undef UINT8_MAX
#define UINT8_MAX __UINT8_MAX__
#endif
#ifdef __UINT16_MAX__
#undef UINT16_MAX
#define UINT16_MAX __UINT16_MAX__
#endif
#ifdef __UINT32_MAX__
#undef UINT32_MAX
#define UINT32_MAX __UINT32_MAX__
#endif
#ifdef __UINT64_MAX__
#undef UINT64_MAX
#define UINT64_MAX __UINT64_MAX__
#endif
#ifdef __INT8_MAX__
#undef INT8_MAX
#define INT8_MAX __INT8_MAX__
#endif
#ifdef __INT16_MAX__
#undef INT16_MAX
#define INT16_MAX __INT16_MAX__
#endif
#ifdef __INT32_MAX__
#undef INT32_MAX
#define INT32_MAX __INT32_MAX__
#endif
#ifdef __INT64_MAX__
#undef INT64_MAX
#define INT64_MAX __INT64_MAX__
#endif
#ifdef __INT8_MAX__
#undef INT8_MIN
#define INT8_MIN (-INT8_MAX - 1)
#endif
#ifdef __INT16_MAX__
#undef INT16_MIN
#define INT16_MIN (-INT16_MAX - 1)
#endif
#ifdef __INT32_MAX__
#undef INT32_MIN
#define INT32_MIN (-INT32_MAX - 1)
#endif
#ifdef __INT64_MAX__
#undef INT64_MIN
#define INT64_MIN (-INT64_MAX - 1)
#endif
#undef UINT_LEAST8_MAX
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
#undef UINT_LEAST16_MAX
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
#undef UINT_LEAST32_MAX
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
#undef UINT_LEAST64_MAX
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
#undef INT_LEAST8_MAX
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
#undef INT_LEAST16_MAX
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
#undef INT_LEAST32_MAX
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
#undef INT_LEAST64_MAX
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
#undef INT_LEAST8_MIN
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
#undef INT_LEAST16_MIN
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
#undef INT_LEAST32_MIN
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
#undef INT_LEAST64_MIN
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
#undef UINT_FAST8_MAX
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
#undef UINT_FAST16_MAX
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
#undef UINT_FAST32_MAX
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
#undef UINT_FAST64_MAX
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
#undef INT_FAST8_MAX
#define INT_FAST8_MAX __INT_FAST8_MAX__
#undef INT_FAST16_MAX
#define INT_FAST16_MAX __INT_FAST16_MAX__
#undef INT_FAST32_MAX
#define INT_FAST32_MAX __INT_FAST32_MAX__
#undef INT_FAST64_MAX
#define INT_FAST64_MAX __INT_FAST64_MAX__
#undef INT_FAST8_MIN
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
#undef INT_FAST16_MIN
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
#undef INT_FAST32_MIN
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
#undef INT_FAST64_MIN
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
#ifdef __UINTPTR_MAX__
#undef UINTPTR_MAX
#define UINTPTR_MAX __UINTPTR_MAX__
#endif
#ifdef __INTPTR_MAX__
#undef INTPTR_MAX
#define INTPTR_MAX __INTPTR_MAX__
#undef INTPTR_MIN
#define INTPTR_MIN (-INTPTR_MAX - 1)
#endif
#undef UINTMAX_MAX
#define UINTMAX_MAX __UINTMAX_MAX__
#undef INTMAX_MAX
#define INTMAX_MAX __INTMAX_MAX__
#undef INTMAX_MIN
#define INTMAX_MIN (-INTMAX_MAX - 1)
#undef PTRDIFF_MAX
#define PTRDIFF_MAX __PTRDIFF_MAX__
#undef PTRDIFF_MIN
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
#undef SIG_ATOMIC_MAX
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#undef SIG_ATOMIC_MIN
#define SIG_ATOMIC_MIN (-SIG_ATOMIC_MAX - 1)
#undef SIZE_MAX
#define SIZE_MAX __SIZE_MAX__
#undef WCHAR_MAX
#define WCHAR_MAX __WCHAR_MAX__
#undef WCHAR_MIN
#define WCHAR_MIN (-WCHAR_MAX - 1)
#undef WINT_MAX
#define WINT_MAX __WINT_MAX__
#undef WINT_MIN
#define WINT_MIN (-WINT_MAX - 1)
#ifdef __INT8_TYPE__
#undef INT8_WIDTH
#define INT8_WIDTH 8
#endif
#ifdef __UINT8_TYPE__
#undef UINT8_WIDTH
#define UINT8_WIDTH 8
#endif
#ifdef __INT16_TYPE__
#undef INT16_WIDTH
#define INT16_WIDTH 16
#endif
#ifdef __UINT16_TYPE__
#undef UINT16_WIDTH
#define UINT16_WIDTH 16
#endif
#ifdef __INT32_TYPE__
#undef INT32_WIDTH
#define INT32_WIDTH 32
#endif
#ifdef __UINT32_TYPE__
#undef UINT32_WIDTH
#define UINT32_WIDTH 32
#endif
#ifdef __INT64_TYPE__
#undef INT64_WIDTH
#define INT64_WIDTH 64
#endif
#ifdef __UINT64_TYPE__
#undef UINT64_WIDTH
#define UINT64_WIDTH 64
#endif
#undef INT_LEAST8_WIDTH
#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef UINT_LEAST8_WIDTH
#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef INT_LEAST16_WIDTH
#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef UINT_LEAST16_WIDTH
#define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef INT_LEAST32_WIDTH
#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef UINT_LEAST32_WIDTH
#define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef INT_LEAST64_WIDTH
#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef UINT_LEAST64_WIDTH
#define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef INT_FAST8_WIDTH
#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef UINT_FAST8_WIDTH
#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef INT_FAST16_WIDTH
#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef UINT_FAST16_WIDTH
#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef INT_FAST32_WIDTH
#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef UINT_FAST32_WIDTH
#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef INT_FAST64_WIDTH
#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__
#undef UINT_FAST64_WIDTH
#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__
#ifdef __INTPTR_TYPE__
#undef INTPTR_WIDTH
#define INTPTR_WIDTH __INTPTR_WIDTH__
#endif
#ifdef __UINTPTR_TYPE__
#undef UINTPTR_WIDTH
#define UINTPTR_WIDTH __INTPTR_WIDTH__
#endif
#undef INTMAX_WIDTH
#define INTMAX_WIDTH __INTMAX_WIDTH__
#undef UINTMAX_WIDTH
#define UINTMAX_WIDTH __INTMAX_WIDTH__
#undef PTRDIFF_WIDTH
#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
#undef SIG_ATOMIC_WIDTH
#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
#undef SIZE_WIDTH
#define SIZE_WIDTH __SIZE_WIDTH__
#undef WCHAR_WIDTH
#define WCHAR_WIDTH __WCHAR_WIDTH__
#undef WINT_WIDTH
#define WINT_WIDTH __WINT_WIDTH__
+1 -1
View File
@@ -1,3 +1,4 @@
// SPDX-License-Identifier: ISC
#pragma once
#include <stddef.h>
@@ -11,4 +12,3 @@ void* memset(void* dest, int value, size_t n);
char* strncpy(char* restrict dst, const char* restrict src, size_t len);
int strcmp(const char* str1, const char* str2);
int strncmp(const char* str1, const char* str2, size_t len);
char* strchr(const char* c, int s);
+3
View File
@@ -1,6 +1,7 @@
#pragma once
#include <zinnia/errno.h>
#include <zinnia/initgraph.h>
#include <zinnia/types.h>
#include <arch/mem.h>
#include <stddef.h>
@@ -51,3 +52,5 @@ void mem_phys_init(struct phys_mem* map, size_t length);
static inline size_t mem_high_shift() {
return arch_mem_level_bits() * arch_mem_num_levels() + arch_mem_page_bits();
}
INIT_EXTERN(mem_stage);
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <zinnia/mman.h>
// TODO
enum bio_type : uint8_t {
BLOCK_READ,
BLOCK_WRITE,
};
struct bio {
enum bio_type type;
uint32_t num_lbas;
uint64_t lba;
};
+8
View File
@@ -2,6 +2,7 @@
#include <zinnia/compiler.h>
#include <zinnia/utils.h>
#include <stddef.h>
#include <stdint.h>
#define _CMDLINE_OPTION(x, opt_name, opt_desc, opt_func) \
@@ -48,3 +49,10 @@ struct cmdline_option {
// Parses the command line and invokes all options.
void cmdline_parse(const char* cmdline);
void cmdline_parse_buf(
char* buf,
size_t len,
const struct cmdline_option* const* start,
const struct cmdline_option* const* end
);
+9 -8
View File
@@ -1,6 +1,7 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/initgraph.h>
#include <zinnia/utils.h>
#include <stddef.h>
@@ -10,16 +11,16 @@ struct console {
bool (*init)(struct console* con);
// Writes to the console.
void (*write)(struct console* con, const char* buf, size_t count);
struct console* next;
};
// Initializes a console for logging.
void console_init();
INIT_EXTERN(console_stage);
// Registers a console.
bool console_register(struct console* con);
// Unregisters a regular console.
void console_unregister(struct console* con);
// Writes a message to a console.
void console_write(const char* buf, size_t len);
// Defines a new early console which can be used to log early boot messages.
// An early console must not make any heap allocations.
#define DEFINE_CONSOLE(con) \
[[__used, __section(".console")]] \
static struct console* UNIQUE_IDENT(console) = (con)
+56 -36
View File
@@ -2,7 +2,7 @@
#include <zinnia/errno.h>
#include <zinnia/vfs.h>
#include <bits/elf.h>
#include <arch/elf.h>
#include <stdint.h>
constexpr char ELF_MAG[4] = {0x7F, 'E', 'L', 'F'};
@@ -74,6 +74,20 @@ enum : uint32_t {
PT_TLS = 0x00000007,
};
enum : uint32_t {
PT_MOD_VERSION = 0x60000001,
PT_MOD_AUTHOR = 0x60000002,
PT_MOD_DESC = 0x60000003,
PT_MOD_LICENSE = 0x60000004,
PT_MOD_CMDLINE = 0x60000005,
PT_MOD_EXIT = 0x60000006,
PT_MOD_MATCH = 0x60000007,
};
enum : uint16_t {
SHN_UNDEF = 0,
};
enum : uint32_t {
PF_X = 0x00000001,
PF_W = 0x00000002,
@@ -110,6 +124,9 @@ enum : uint32_t {
DT_FINI_ARRAY = 26,
DT_INIT_ARRAYSZ = 27,
DT_FINI_ARRAYSZ = 28,
DT_RELRSZ = 35,
DT_RELR = 36,
DT_RELRENT = 37,
DT_LOOS = 0x60000000,
DT_HIOS = 0x6FFFFFFF,
DT_LOPROC = 0x70000000,
@@ -140,7 +157,7 @@ enum : uint32_t {
AT_INIT_HANDLE = 0x1000,
};
struct elf64_ehdr {
typedef struct {
uint8_t e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
@@ -155,9 +172,9 @@ struct elf64_ehdr {
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
};
} elf64_ehdr_t;
struct elf32_ehdr {
typedef struct {
uint8_t e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
@@ -172,9 +189,9 @@ struct elf32_ehdr {
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
};
} elf32_ehdr_t;
struct elf64_phdr {
typedef struct {
uint32_t p_type;
uint32_t p_flags;
elf64_off_t p_offset;
@@ -183,9 +200,9 @@ struct elf64_phdr {
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
};
} elf64_phdr_t;
struct elf32_phdr {
typedef struct {
uint32_t p_type;
elf32_off_t p_offset;
elf32_addr_t p_vaddr;
@@ -194,68 +211,68 @@ struct elf32_phdr {
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
};
} elf32_phdr_t;
struct elf64_dyn {
typedef struct {
int64_t d_tag;
union {
uint64_t d_val;
elf64_addr_t d_ptr;
} d_un;
};
} elf64_dyn_t;
struct elf32_dyn {
typedef struct {
int32_t r_offset;
union {
uint32_t d_val;
elf32_addr_t d_ptr;
} d_un;
};
} elf32_dyn_t;
struct elf64_nhdr {
typedef struct {
uint64_t n_namesz;
uint64_t n_descsz;
uint64_t n_type;
};
} elf64_nhdr_t;
struct elf32_nhdr {
typedef struct {
uint32_t n_namesz;
uint32_t n_descsz;
uint32_t n_type;
};
} elf32_nhdr_t;
struct elf64_auxv {
typedef struct {
uint64_t atype;
uint64_t avalue;
};
} elf64_auxv_t;
struct elf32_auxv {
typedef struct {
uint32_t atype;
uint32_t avalue;
};
} elf32_auxv_t;
struct elf_hash {
typedef struct {
uint32_t n_buckets;
uint32_t n_chain;
};
} elf_hash_t;
struct elf32_sym {
typedef struct {
elf32_off_t st_name;
elf32_addr_t st_value;
elf32_off_t st_size;
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
};
} elf32_sym_t;
struct elf64_sym {
typedef struct {
uint32_t st_name;
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
uint64_t st_value;
uint64_t st_size;
};
} elf64_sym_t;
static uint8_t ELF64_ST_BIND(uint8_t info) {
return info >> 4;
@@ -272,7 +289,7 @@ static inline uint8_t ELF64_ST_INFO(uint8_t bind, uint8_t type) {
typedef struct {
uint16_t si_boundto;
uint16_t si_flags;
} elf64_syminfo;
} elf64_syminfo_t;
static inline uint8_t ELF32_ST_BIND(uint8_t info) {
return info >> 4;
@@ -304,27 +321,30 @@ enum {
STT_HIPROC = 15
};
struct elf32_rela {
typedef struct {
elf32_addr_t r_offset;
uint32_t r_info;
int32_t r_addend;
};
} elf32_rela_t;
struct elf64_rela {
typedef struct {
elf64_addr_t r_offset;
uint64_t r_info;
int64_t r_addend;
};
} elf64_rela_t;
struct elf32_rel {
typedef uint64_t elf64_relr_t;
typedef uint32_t elf32_relr_t;
typedef struct {
elf32_addr_t r_offset;
uint32_t r_info;
};
} elf32_rel_t;
struct elf64_rel {
typedef struct {
elf64_addr_t r_offset;
uint64_t r_info;
};
} elf64_rel_t;
static inline uint32_t ELF32_R_SYM(uint32_t info) {
return info >> 8;
-1
View File
@@ -4,7 +4,6 @@
#include <uapi/errno.h>
typedef enum : int32_t {
EOK = 0, // Success! Not really an error though...
EPERM = __EPERM,
ENOENT = __ENOENT,
ESRCH = __ESRCH,
+22
View File
@@ -21,8 +21,18 @@ constexpr uint32_t FDT_END_NODE = 0x00000002;
constexpr uint32_t FDT_PROP = 0x00000003;
constexpr uint32_t FDT_NOP = 0x00000004;
constexpr uint32_t FDT_END = 0x00000009;
constexpr uint32_t FDT_MAGIC = 0xD00DFEED;
struct fdt_match {
const char* compatible;
uintptr_t data;
};
#define FDT_MATCH_COMPATIBLE(compat) .compatible = (compat)
struct fdt {
const uint8_t* blob;
size_t total_size;
uint32_t version;
uint32_t compat_version;
uint32_t boot_cpuid;
@@ -35,11 +45,23 @@ struct fdt {
struct fdt_node {
struct fdt* tree;
size_t offset;
};
struct fdt_prop {
struct fdt* tree;
const void* data;
size_t length;
};
uint32_t fdt_read_u32(const void* data);
uint64_t fdt_read_u64(const void* data);
bool fdt_init(struct fdt* tree, const void* data, size_t length);
struct fdt_node fdt_find(struct fdt* tree, const char* path);
struct fdt_node fdt_find_compatible(struct fdt* tree, const char* compatible);
struct fdt_prop fdt_property(struct fdt_node node, const char* name);
bool fdt_property_u32(struct fdt_node node, const char* name, uint32_t* value);
bool fdt_property_u64(struct fdt_node node, const char* name, uint64_t* value);
// Root of the device tree.
struct fdt_node fdt_root(struct fdt* tree);
+1 -1
View File
@@ -4,7 +4,7 @@
#include <zinnia/errno.h>
#include <stddef.h>
#include <stdint.h>
#include <zinnia/string.h>
#include <string.h>
#define hashmap(K, V) \
struct { \
+1
View File
@@ -38,6 +38,7 @@ struct boot_info {
struct boot_file* files;
size_t num_files;
struct boot_framebuffer fb;
struct boot_file kernel_file;
void* dtb;
size_t dtb_size;
#if CONFIG_ACPI
+82
View File
@@ -0,0 +1,82 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/utils.h>
#include <stddef.h>
enum init_action {
INIT_EMPTY,
INIT_CALLBACK,
INIT_GATE,
};
struct boot_info;
struct init_node;
struct init_edge {
struct init_node* source;
struct init_node* target;
bool propagates_disable;
struct init_edge* next_in;
struct init_edge* next_out;
};
struct init_edges {
struct init_node* node;
bool depends;
size_t count;
struct init_node* const* nodes;
struct init_edge* edges;
};
struct init_node {
const char* name;
enum init_action action;
union {
void (*callback)(struct boot_info* info);
bool (*gate)(struct boot_info* info);
void* func;
};
size_t unsatisfied;
bool wanted;
bool done;
bool disabled;
struct init_edge* in_edges;
struct init_edge* out_edges;
struct init_node* queue_next;
};
#define INIT_EXTERN(node) extern struct init_node node[1]
#define INIT_TASK(node, display, ...) \
struct init_node node[1] = {{ \
.name = (display), \
__VA_OPT__( \
.action = _Generic( \
(__VA_ARGS__), \
void (*)(struct boot_info*): INIT_CALLBACK, \
bool (*)(struct boot_info*): INIT_GATE \
), \
.func = (void*)(__VA_ARGS__), \
) \
}}; \
[[__used, __section(".initgraph.nodes")]] \
static struct init_node* const CONCAT(node, _initgraph_node) = node
#define _INIT_EDGES(x, from, is_depends, ...) \
static struct init_node* const CONCAT(x, _nodes)[] = {__VA_ARGS__}; \
static struct init_edge CONCAT(x, _edges)[ARRAY_SIZE(CONCAT(x, _nodes))]; \
static const struct init_edges x = { \
.node = (from), \
.depends = (is_depends), \
.count = ARRAY_SIZE(CONCAT(x, _nodes)), \
.nodes = CONCAT(x, _nodes), \
.edges = CONCAT(x, _edges), \
}; \
[[__used, __section(".initgraph.edges")]] \
static const struct init_edges* const CONCAT(x, _ptr) = &x
#define INIT_DEPENDS(node, ...) _INIT_EDGES(UNIQUE_IDENT(init_edges), node, true, __VA_ARGS__)
#define INIT_ENTAILS(node, ...) _INIT_EDGES(UNIQUE_IDENT(init_edges), node, false, __VA_ARGS__)
void initgraph_run(struct init_node* goal, struct boot_info* info);
-1
View File
@@ -1,7 +1,6 @@
#pragma once
#include <zinnia/errno.h>
#include <zinnia/string.h>
#include <zinnia/usercopy.h>
#include <zinnia/utils.h>
#include <stddef.h>
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <zinnia/initgraph.h>
#include <stddef.h>
#include <stdint.h>
void ksym_init();
// Finds the function containing `addr`. Returns false if no symbol is known.
bool ksym_lookup(uintptr_t addr, const char** name, size_t* offset);
// Writes `name+0xoffset` for `addr` to `buf`, or `<???>` if the address can't be resolved.
void ksym_format(uintptr_t addr, char* buf, size_t size);
bool ksym_find(const char* name, uintptr_t* addr);
const char* ksym_kernel_name();
INIT_EXTERN(ksyms_stage);
+65 -14
View File
@@ -1,7 +1,11 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/errno.h>
#include <zinnia/initgraph.h>
#include <zinnia/tailq.h>
#include <zinnia/types.h>
#include <zinnia/utils.h>
#include <stddef.h>
#include <stdint.h>
#define MODULE_PROPERTY(name, data) \
@@ -13,36 +17,83 @@
#define MODULE_VERSION(version) MODULE_PROPERTY("version", version)
#define MODULE_LICENSE(license) MODULE_PROPERTY("license", license)
#ifdef IN_MODULE
struct match_table {
const char* name;
const void* entries;
size_t size;
};
#ifdef __IN_MODULE
#define MATCH_TABLE(match_name, table) \
[[__used, __section(".mod.match"), __aligned(8)]] \
static const struct match_table CONCAT(table, _match_table) = { \
.name = (match_name), \
.entries = (table), \
.size = ARRAY_SIZE(table), \
}
#else
#define MATCH_TABLE(match_name, table) static_assert(true)
#endif
// Module entries are used
#ifdef __IN_MODULE
#define MODULE_ENTRY(func) \
[[__used]] \
[[__used, __visibility("hidden")]] \
errno_t __module_entry(struct module* __module) { \
return func(__module); \
} \
}
#else
#define MODULE_ENTRY(func) \
[[__used, __section(".mod.entry")]] \
static const void* __entry_fn = &__module_entry
static errno_t (*const UNIQUE_IDENT(module_entry))(struct module*) = &(func)
#endif
#ifdef __IN_MODULE
#define MODULE_EXIT(func) \
[[__used]] \
[[__used, __visibility("hidden")]] \
errno_t __module_exit(struct module* __module) { \
return func(__module); \
} \
[[__used, __section(".mod.exit")]] \
static const void* __exit_fn = &__module_exit
static errno_t (*const __exit_fn)(struct module*) = &__module_exit
#else
#define MODULE_ENTRY(func) \
[[__used, __section(".mod.entry")]] \
static const void* UNIQUE_IDENT(module_entry) = &(func)
#define MODULE_EXIT(func) \
[[__used, __section(".mod.exit")]] \
static const void* UNIQUE_IDENT(module_exit) = &(func)
// Built-in drivers can't be unloaded.
#define MODULE_EXIT(func) static_assert(&(func) != nullptr)
#endif
struct module_segment {
phys_t phys;
uintptr_t virt;
size_t size;
};
struct module {
const char* name;
const char* version;
const char* author;
const char* desc;
const char* license;
uintptr_t base;
size_t size;
uintptr_t bias;
const void* symtab;
size_t num_syms;
const char* strtab;
size_t strtab_size;
struct module_segment* segments;
size_t num_segments;
errno_t (*exit)(struct module*);
char* cmdline;
tailq_link(struct module) link;
};
#define THIS_MODULE (struct module*)nullptr
void module_init();
struct boot_info;
void module_init(struct boot_info* info);
errno_t module_load(const void* data, size_t length, const char* cmdline, struct module** out);
errno_t module_unload(struct module* mod);
struct module* module_find(const char* name);
INIT_EXTERN(module_stage);
+187
View File
@@ -0,0 +1,187 @@
#pragma once
#include <zinnia/alloc.h>
#include <zinnia/compiler.h>
#include <zinnia/errno.h>
#include <zinnia/initgraph.h>
#include <zinnia/print.h>
#include <zinnia/types.h>
#include <stddef.h>
#include <stdint.h>
struct pci_address {
uint16_t domain;
uint8_t bus;
uint8_t device;
uint8_t function;
};
#define PCI_ADDR_FMT "%.4hx:%.2hhx:%.2hhx.%hhx"
#define PCI_ADDR_ARGS(a) (a)->domain, (a)->bus, (a)->device, (a)->function
struct pci_id {
uint16_t vendor_id;
uint16_t device_id;
uint16_t subvendor_id;
uint16_t subdevice_id;
};
struct pci_class {
uint8_t class;
uint8_t subclass;
uint8_t prog_if;
};
enum pci_cfg : uint16_t {
PCI_VENDOR_ID = 0x00,
PCI_DEVICE_ID = 0x02,
PCI_COMMAND = 0x04,
PCI_STATUS = 0x06,
PCI_PROG_IF = 0x09,
PCI_SUBCLASS = 0x0a,
PCI_CLASS = 0x0b,
PCI_HEADER_TYPE = 0x0e,
PCI_BAR0 = 0x10,
PCI_SECONDARY_BUS = 0x19,
PCI_SUBSYS_VENDOR_ID = 0x2c,
PCI_SUBSYS_ID = 0x2e,
PCI_CAP_PTR = 0x34,
PCI_INTERRUPT_LINE = 0x3c,
PCI_INTERRUPT_PIN = 0x3d,
};
enum pci_command : uint16_t {
PCI_COMMAND_IO = 1 << 0,
PCI_COMMAND_MEM = 1 << 1,
PCI_COMMAND_MASTER = 1 << 2,
PCI_COMMAND_INTX_DISABLE = 1 << 10,
};
constexpr uint16_t PCI_STATUS_CAP_LIST = 1 << 4;
constexpr uint8_t PCI_HEADER_TYPE_MASK = 0x7f;
constexpr uint8_t PCI_HEADER_TYPE_MULTIFUNCTION = 0x80;
constexpr uint8_t PCI_HEADER_TYPE_BRIDGE = 0x01;
constexpr size_t PCI_NUM_BARS = 6;
constexpr uint8_t PCI_NUM_SLOTS = 32;
constexpr uint8_t PCI_NUM_FUNCTIONS = 8;
enum pci_cap_id : uint8_t {
PCI_CAP_MSI = 0x05,
PCI_CAP_PCIE = 0x10,
PCI_CAP_MSIX = 0x11,
};
struct pci_access {
const char* name;
uint16_t domain;
uint8_t start_bus;
uint8_t end_bus;
uint8_t priority;
uint32_t (*read32)(struct pci_access* self, const struct pci_address* addr, uint16_t offset);
void (*write32)(struct pci_access* self, const struct pci_address* addr, uint16_t offset, uint32_t value);
};
enum pci_access_priority : uint8_t {
PCI_ACCESS_PRIO_LEGACY = 0,
PCI_ACCESS_PRIO_ECAM = 128,
};
static bool pci_access_decodes(const struct pci_access* access, const struct pci_address* addr);
errno_t pci_access_register(struct pci_access* access);
struct pci_access* pci_access_find(const struct pci_address* addr);
errno_t pci_ecam_register(phys_t base, uint16_t domain, uint8_t start_bus, uint8_t end_bus);
struct pci_driver;
struct pci_device {
struct pci_address address;
struct pci_id id;
struct pci_class class;
struct pci_access* access;
uint8_t header_type;
struct pci_driver* driver;
};
uint8_t pci_read8(struct pci_device* dev, uint16_t offset);
uint16_t pci_read16(struct pci_device* dev, uint16_t offset);
uint32_t pci_read32(struct pci_device* dev, uint16_t offset);
void pci_write8(struct pci_device* dev, uint16_t offset, uint8_t value);
void pci_write16(struct pci_device* dev, uint16_t offset, uint16_t value);
void pci_write32(struct pci_device* dev, uint16_t offset, uint32_t value);
enum pci_bar_type : uint8_t {
PCI_BAR_NONE,
PCI_BAR_MMIO32,
PCI_BAR_MMIO64,
PCI_BAR_IO,
};
struct pci_bar {
enum pci_bar_type type;
bool prefetchable;
phys_t address;
size_t size;
};
errno_t pci_bar_get(struct pci_device* dev, size_t index, struct pci_bar* out);
uint8_t pci_cap_next(struct pci_device* dev, uint8_t cur);
uint8_t pci_cap_find(struct pci_device* dev, uint8_t id);
#define PCI_ANY_ID 0xffff
#define PCI_ANY_CLASS 0xff
// Matches a device by ID and class.
struct pci_match {
uint16_t vendor_id;
uint16_t device_id;
uint8_t class;
uint8_t subclass;
uint8_t prog_if;
// Not used to match, but can be used to pass device-specific context data.
uintptr_t data;
};
#define PCI_MATCH_DEVICE(vendor, device) \
.vendor_id = (vendor), .device_id = (device), .class = PCI_ANY_CLASS, .subclass = PCI_ANY_CLASS, \
.prog_if = PCI_ANY_CLASS
#define PCI_MATCH_CLASS(c, sc, pi) \
.vendor_id = PCI_ANY_ID, .device_id = PCI_ANY_ID, .class = (c), .subclass = (sc), .prog_if = (pi)
// Writes the address to `buf`.
static void pci_device_name(const struct pci_device* dev, char buf[static 18]);
struct pci_driver {
const char* name;
// Match table, array of `num_matches` entries, checked sequentially.
// When writing a match table, the most specific matches should come first, then more generic cases.
const struct pci_match* match;
const size_t num_matches;
errno_t (*probe)(struct pci_device* dev, const struct pci_match* match);
};
errno_t pci_driver_register(struct pci_driver* driver);
INIT_EXTERN(pci_stage);
#ifdef __MODULE_NAME
#define PCI_LOG_NAME __MODULE_NAME
#else
#define PCI_LOG_NAME "pci"
#endif
#define pci_log_level(level, dev, message, ...) \
log_write(level, PCI_LOG_NAME " " PCI_ADDR_FMT ": " message, PCI_ADDR_ARGS(&(dev)->address), ##__VA_ARGS__)
#define pci_log_debug(dev, message, ...) pci_log_level(LOG_DEBUG, dev, message, ##__VA_ARGS__)
#define pci_log(dev, message, ...) pci_log_level(LOG_INFO, dev, message, ##__VA_ARGS__)
#define pci_log_warn(dev, message, ...) pci_log_level(LOG_WARN, dev, message, ##__VA_ARGS__)
#define pci_log_err(dev, message, ...) pci_log_level(LOG_ERR, dev, message, ##__VA_ARGS__)
+4 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/initgraph.h>
#include <zinnia/sched.h>
#include <zinnia/usercopy.h>
#include <stddef.h>
@@ -40,7 +41,9 @@ struct percpu* percpu_new();
size_t percpu_max_cpus();
struct percpu* percpu_get();
void percpu_bsp_init();
void percpu_init();
void percpu_init(struct boot_info* info);
INIT_EXTERN(percpu_stage);
// Per-CPU data for the bootstrap processor.
extern struct percpu percpu_bsp;
+35 -9
View File
@@ -2,19 +2,45 @@
#include <zinnia/compiler.h>
#include <stdarg.h>
#include <stddef.h>
[[__format(printf, 1, 2)]]
void kprintf(const char* message, ...);
void kvprintf(const char* message, va_list args);
#include <zinnia/clock.h>
#include <zinnia/percpu.h>
[[__format(printf, 3, 4)]]
size_t ksnprintf(char* buf, size_t size, const char* format, ...);
#define log(message, ...) \
do { \
auto _time = clock_get_elapsed_ns(); \
auto _cur = percpu_get()->sched.current; \
auto _tid = _cur ? _cur->id : 0; \
kprintf("[%5lu.%06lu] [%5lu] " message, _time / 1'000'000'000, _time / 1'000 % 1'000'000, _tid, ##__VA_ARGS__); \
} while (0)
size_t kvsnprintf(char* buf, size_t size, const char* format, va_list args);
typedef void (*log_fn_t)(void* ctx, const char* buf, size_t len);
void print_fmt(log_fn_t callback, void* ctx, const char* restrict fmt, va_list args);
enum log_level {
LOG_DEBUG,
LOG_STATUS,
LOG_INFO,
LOG_WARN,
LOG_ERR,
LOG_PANIC,
};
[[__format(printf, 2, 3)]]
void log_write(enum log_level level, const char* message, ...);
void log_vwrite(enum log_level level, const char* message, va_list args);
// Like log_vwrite(), but prepends a `prefix` to the message.
void log_vwrite_prefixed(enum log_level level, const char* prefix, const char* message, va_list args);
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
#define log(message, ...) log_write(LOG_INFO, pr_fmt(message), ##__VA_ARGS__)
#define log_debug(message, ...) log_write(LOG_DEBUG, pr_fmt(message), ##__VA_ARGS__)
#define log_status(message, ...) log_write(LOG_STATUS, pr_fmt(message), ##__VA_ARGS__)
#define log_warn(message, ...) log_write(LOG_WARN, pr_fmt(message), ##__VA_ARGS__)
#define log_err(message, ...) log_write(LOG_ERR, pr_fmt(message), ##__VA_ARGS__)
#define log_panic(message, ...) log_write(LOG_PANIC, pr_fmt(message), ##__VA_ARGS__)
+12
View File
@@ -2,10 +2,12 @@
#include <zinnia/errno.h>
#include <zinnia/init.h>
#include <zinnia/initgraph.h>
#include <zinnia/stack.h>
#include <zinnia/tailq.h>
#include <zinnia/types.h>
#include <bits/sched.h>
#include <stdatomic.h>
#include <stddef.h>
#include <stdint.h>
@@ -34,6 +36,7 @@ struct task {
uintptr_t user_stack;
size_t time_slice;
int8_t priority;
atomic_bool wake_pending;
tailq_link(struct task) next;
};
@@ -57,6 +60,13 @@ void sched_init(struct scheduler* sched);
void sched_reschedule(struct scheduler* sched);
void sched_yield(struct scheduler* sched);
void sched_add_task(struct scheduler* sched, struct task* task);
// Blocks the current task until sched_wake() is called on it.
// Returns immediately if a wake is already pending. Must not hold any spinlock.
void sched_block(struct scheduler* sched);
// Makes a blocked task runnable again, or marks the wake as pending if it hasn't blocked yet.
void sched_wake(struct task* task);
[[noreturn]]
void sched_to_user(uintptr_t ctx);
[[noreturn]]
@@ -68,3 +78,5 @@ struct task_start_info {
uintptr_t sp;
uintptr_t arg;
};
INIT_EXTERN(sched_stage);
-1
View File
@@ -1,6 +1,5 @@
#pragma once
#include <stdatomic.h>
#include <stdint.h>
// Busy-waits in a loop until the lock is freed.
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
#define USB_ANY_ID 0xffff
#define USB_ANY_CLASS 0xff
struct usb_match {
uint16_t vendor_id;
uint16_t product_id;
uint8_t class;
uint8_t subclass;
uint8_t protocol;
uintptr_t data;
};
#define USB_MATCH_DEVICE(vendor, product) \
.vendor_id = (vendor), .product_id = (product), .class = USB_ANY_CLASS, .subclass = USB_ANY_CLASS, \
.protocol = USB_ANY_CLASS
#define USB_MATCH_CLASS(c, sc, p) \
.vendor_id = USB_ANY_ID, .product_id = USB_ANY_ID, .class = (c), .subclass = (sc), .protocol = (p)
+1 -1
View File
@@ -3,7 +3,7 @@
#include <zinnia/alloc.h>
#include <zinnia/errno.h>
#include <stddef.h> // IWYU pragma: keep
#include <zinnia/string.h> // IWYU pragma: keep
#include <string.h> // IWYU pragma: keep
#define vec(T) \
struct { \