kernel: don't use typedef for enums or non-opaque structs

This commit is contained in:
2023-04-12 20:17:11 +01:00
parent 0d75e347e9
commit b6f8c1ccaa
51 changed files with 663 additions and 665 deletions

View File

@@ -29,12 +29,12 @@
extern "C" {
#endif
/* if your custom structure contains a btree_node_t (i.e. it can be part of a btree),
you can use this macro to convert a btree_node_t* to a your_type*
/* if your custom structure contains a struct btree_node (i.e. it can be part of a btree),
you can use this macro to convert a struct btree_node* to a your_type*
@param t the name of your custom type (something that can be passed to offsetof)
@param m the name of the btree_node_t member variable within your custom type.
@param v the btree_node_t pointer that you wish to convert. if this is NULL, NULL will be returned.
@param m the name of the struct btree_node member variable within your custom type.
@param v the struct btree_node pointer that you wish to convert. if this is NULL, NULL will be returned.
*/
#define BTREE_CONTAINER(t, m, v) ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0))
@@ -46,7 +46,7 @@ extern "C" {
struct my_tree_node {
int key;
btree_node_t base;
struct btree_node base;
}
You would use the following call to generate an insert function for a tree with this node type:
@@ -55,15 +55,15 @@ extern "C" {
Which would emit a function defined like:
static void my_tree_node_insert(btree_t *tree, struct my_tree_node *node);
static void my_tree_node_insert(struct btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that contains a btree_node_t member.
@param container_node_member the name of the btree_node_t member variable within your custom type.
@param node_type your custom tree node type. usually a structure that contains a struct btree_node member.
@param container_node_member the name of the struct btree_node member variable within your custom type.
@param container_key_member the name of the key member variable within your custom type.
@param function_name the name of the function to generate.
*/
#define BTREE_DEFINE_SIMPLE_INSERT(node_type, container_node_member, container_key_member, function_name) \
static void function_name(btree_t *tree, node_type *node) \
static void function_name(struct btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
@@ -71,10 +71,10 @@ extern "C" {
return; \
} \
\
btree_node_t *cur = tree->b_root; \
struct btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \
btree_node_t *next = NULL; \
struct btree_node *next = NULL; \
\
if (node->container_key_member > cur_node->container_key_member) { \
next = btree_right(cur); \
@@ -109,7 +109,7 @@ extern "C" {
struct my_tree_node {
complex_key_t key;
btree_node_t base;
struct btree_node base;
}
You would need to define a comparator function or macro with the following signature:
@@ -128,17 +128,17 @@ extern "C" {
Which would emit a function defined like:
static void my_tree_node_insert(btree_t *tree, struct my_tree_node *node);
static void my_tree_node_insert(struct btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that contains a btree_node_t member.
@param container_node_member the name of the btree_node_t member variable within your custom type.
@param node_type your custom tree node type. usually a structure that contains a struct btree_node member.
@param container_node_member the name of the struct btree_node member variable within your custom type.
@param container_key_member the name of the key member variable within your custom type.
@param function_name the name of the function to generate.
@param comparator the name of a comparator function or functional-macro that conforms to the
requirements listed above.
*/
#define BTREE_DEFINE_INSERT(node_type, container_node_member, container_key_member, function_name, comparator) \
static void function_name(btree_t *tree, node_type *node) \
static void function_name(struct btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
@@ -146,10 +146,10 @@ extern "C" {
return; \
} \
\
btree_node_t *cur = tree->b_root; \
struct btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \
btree_node_t *next = NULL; \
struct btree_node *next = NULL; \
int cmp = comparator(node, cur_node); \
\
if (cmp == 1) { \
@@ -184,7 +184,7 @@ extern "C" {
struct my_tree_node {
int key;
btree_node_t base;
struct btree_node base;
}
You would use the following call to generate a search function for a tree with this node type:
@@ -193,19 +193,19 @@ extern "C" {
Which would emit a function defined like:
static struct my_tree_node *my_tree_node_get(btree_t *tree, int key);
static struct my_tree_node *my_tree_node_get(struct btree *tree, int key);
@param node_type your custom tree node type. usually a structure that contains a btree_node_t member.
@param node_type your custom tree node type. usually a structure that contains a struct btree_node member.
@param key_type the type name of the key embedded in your custom tree node type. this type must be
compatible with the builtin comparison operators.
@param container_node_member the name of the btree_node_t member variable within your custom type.
@param container_node_member the name of the struct btree_node member variable within your custom type.
@param container_key_member the name of the key member variable within your custom type.
@param function_name the name of the function to generate.
*/
#define BTREE_DEFINE_SIMPLE_GET(node_type, key_type, container_node_member, container_key_member, function_name) \
node_type *function_name(btree_t *tree, key_type key) \
node_type *function_name(struct btree *tree, key_type key) \
{ \
btree_node_t *cur = tree->b_root; \
struct btree_node *cur = tree->b_root; \
while (cur) { \
node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \
if (key > cur_node->container_key_member) { \
@@ -224,13 +224,13 @@ node_type *function_name(btree_t *tree, key_type key) \
If you have a tree defined like:
btree_t my_tree;
struct btree my_tree;
with nodes defined like:
struct my_tree_node {
int key;
btree_node_t base;
struct btree_node base;
}
and you want to do something like:
@@ -244,7 +244,7 @@ node_type *function_name(btree_t *tree, key_type key) \
@param iter_type the type name of the iterator variable. this should be the tree's node type, and shouldn't be a pointer.
@param iter_name the name of the iterator variable.
@param tree_name a pointer to the tree to traverse.
@param node_member the name of the btree_node_t member variable within the tree node type.
@param node_member the name of the struct btree_node member variable within the tree node type.
*/
#define btree_foreach(iter_type, iter_name, tree_name, node_member) \
for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_first(tree_name)); \
@@ -255,13 +255,13 @@ node_type *function_name(btree_t *tree, key_type key) \
If you have a tree defined like:
btree_t my_tree;
struct btree my_tree;
with nodes defined like:
struct my_tree_node {
int key;
btree_node_t base;
struct btree_node base;
}
and you want to do something like:
@@ -275,7 +275,7 @@ node_type *function_name(btree_t *tree, key_type key) \
@param iter_type the type name of the iterator variable. this should be the tree's node type, and shouldn't be a pointer.
@param iter_name the name of the iterator variable.
@param tree_name a pointer to the tree to traverse.
@param node_member the name of the btree_node_t member variable within the tree node type.
@param node_member the name of the struct btree_node member variable within the tree node type.
*/
#define btree_foreach_r(iter_type, iter_name, tree_name, node_member) \
for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_last(tree_name)); \
@@ -283,19 +283,19 @@ node_type *function_name(btree_t *tree, key_type key) \
iter_name = BTREE_CONTAINER(iter_type, node_member, btree_prev(&((iter_name)->node_member))))
/* binary tree nodes. this *cannot* be used directly. you need to define a custom node type
that contains a member variable of type btree_node_t.
that contains a member variable of type struct btree_node.
you would then use the supplied macros to define functions to manipulate your custom binary tree.
*/
typedef struct btree_node {
struct btree_node {
struct btree_node *b_parent, *b_left, *b_right;
unsigned short b_height;
} btree_node_t;
};
/* binary tree. unlike btree_node_t, you can define variables of type btree_t. */
typedef struct btree {
/* binary tree. unlike struct btree_node, you can define variables of type struct btree. */
struct btree {
struct btree_node *b_root;
} btree_t;
};
/* re-balance a binary tree after an insertion operation.
@@ -305,59 +305,59 @@ typedef struct btree {
@param tree the tree to re-balance.
@param node the node that was just inserted into the tree.
*/
extern void btree_insert_fixup(btree_t *tree, btree_node_t *node);
extern void btree_insert_fixup(struct btree *tree, struct btree_node *node);
/* delete a node from a binary tree and re-balance the tree afterwards.
@param tree the tree to delete from
@param node the node to delete.
*/
extern void btree_delete(btree_t *tree, btree_node_t *node);
extern void btree_delete(struct btree *tree, struct btree_node *node);
/* get the first node in a binary tree.
this will be the node with the smallest key (i.e. the node that is furthest-left from the root)
*/
extern btree_node_t *btree_first(btree_t *tree);
extern struct btree_node *btree_first(struct btree *tree);
/* get the last node in a binary tree.
this will be the node with the largest key (i.e. the node that is furthest-right from the root)
*/
extern btree_node_t *btree_last(btree_t *tree);
extern struct btree_node *btree_last(struct btree *tree);
/* for any binary tree node, this function returns the node with the next-largest key value */
extern btree_node_t *btree_next(btree_node_t *node);
extern struct btree_node *btree_next(struct btree_node *node);
/* for any binary tree node, this function returns the node with the next-smallest key value */
extern btree_node_t *btree_prev(btree_node_t *node);
extern struct btree_node *btree_prev(struct btree_node *node);
/* sets `child` as the immediate left-child of `parent` */
static inline void btree_put_left(btree_node_t *parent, btree_node_t *child)
static inline void btree_put_left(struct btree_node *parent, struct btree_node *child)
{
parent->b_left = child;
child->b_parent = parent;
}
/* sets `child` as the immediate right-child of `parent` */
static inline void btree_put_right(btree_node_t *parent, btree_node_t *child)
static inline void btree_put_right(struct btree_node *parent, struct btree_node *child)
{
parent->b_right = child;
child->b_parent = parent;
}
/* get the immediate left-child of `node` */
static inline btree_node_t *btree_left(btree_node_t *node)
static inline struct btree_node *btree_left(struct btree_node *node)
{
return node->b_left;
}
/* get the immediate right-child of `node` */
static inline btree_node_t *btree_right(btree_node_t *node)
static inline struct btree_node *btree_right(struct btree_node *node)
{
return node->b_right;
}
/* get the immediate parent of `node` */
static inline btree_node_t *btree_parent(btree_node_t *node)
static inline struct btree_node *btree_parent(struct btree_node *node)
{
return node->b_parent;
}
@@ -369,7 +369,7 @@ static inline btree_node_t *btree_parent(btree_node_t *node)
this count includes the node itself, so the height of a leaf node will be 1.
*/
static inline unsigned short btree_height(btree_node_t *node)
static inline unsigned short btree_height(struct btree_node *node)
{
return node->b_height;
}

View File

@@ -6,7 +6,7 @@
Consoles are like simplified TTYs. Their purpose is to serve as an output
sink for messages printed using printk.
a console_t could be used to represent a serial port, UART port, or even
a struct console could be used to represent a serial port, UART port, or even
a text-based framebuffer display. Anything where the job of displaying
or sending text can be abstracted to a simple write() call.
@@ -22,29 +22,29 @@
extern "C" {
#endif
typedef enum console_flags {
enum console_flags {
/* console is only used during the boot process. the console
will be automatically de-registered when the first
non-boot console is registered */
CON_BOOT = 0x01u,
} console_flags_t;
};
typedef struct console {
struct console {
char c_name[16];
console_flags_t c_flags;
enum console_flags c_flags;
spin_lock_t c_lock;
void (*c_write)(struct console *, const char *, unsigned int);
int (*c_read)(struct console *, char *, unsigned int);
queue_entry_t c_list;
} console_t;
struct queue_entry c_list;
};
extern kern_status_t console_register(console_t *con);
extern kern_status_t console_unregister(console_t *con);
extern kern_status_t console_register(struct console *con);
extern kern_status_t console_unregister(struct console *con);
extern void console_write(console_t *con, const char *s, unsigned int len);
extern int console_read(console_t *con, char *s, unsigned int len);
extern void console_write(struct console *con, const char *s, unsigned int len);
extern int console_read(struct console *con, char *s, unsigned int len);
#ifdef __cplusplus
}

View File

@@ -8,18 +8,18 @@
extern "C" {
#endif
typedef enum cpu_flags {
enum cpu_flags {
CPU_ONLINE = 0x01u,
} cpu_flags_t;
};
typedef struct cpu_data {
cpu_flags_t c_flags;
struct cpu_data {
enum cpu_flags c_flags;
unsigned int c_id;
unsigned int c_preempt_count;
thread_t *c_current_thread;
runqueue_t c_rq;
} cpu_data_t;
struct thread *c_current_thread;
struct runqueue c_rq;
};
/* maximum number of processor cores that the kernel can support.
TODO move to build config option */
@@ -27,8 +27,8 @@ typedef struct cpu_data {
#define this_cpu() (ml_cpu_block_get_id(ml_this_cpu()))
extern cpu_data_t *get_this_cpu(void);
extern void put_cpu(cpu_data_t *cpu);
extern struct cpu_data *get_this_cpu(void);
extern void put_cpu(struct cpu_data *cpu);
extern void cpu_set_available(unsigned int cpu_id);
extern void cpu_set_online(unsigned int cpu_id);

View File

@@ -69,8 +69,8 @@ struct bus_device {
struct device {
enum device_type dev_type;
struct device *dev_parent;
queue_t dev_children;
queue_entry_t dev_childent;
struct queue dev_children;
struct queue_entry dev_childent;
void *dev_priv;

View File

@@ -72,7 +72,7 @@ struct kext {
enum kext_flags k_flags;
char k_ident[KEXT_IDENT_MAX];
uint64_t k_ident_hash;
btree_node_t k_node;
struct btree_node k_node;
kern_status_t(*k_online)(struct kext *);
kern_status_t(*k_offline)(struct kext *);

View File

@@ -45,7 +45,7 @@ extern "C" {
this iteration can be optionally constrained to a given region.
@param i the iterator. this should be a pointer of type memblock_iter_t.
@param i the iterator. this should be a pointer of type struct memblock_iter.
for each iteration, this structure will be filled with details about
the current memory region.
@param p_start the lower bound of the memory region to iterate through.
@@ -55,14 +55,14 @@ extern "C" {
EXAMPLE: to iterate through all memory regions (with no bounds):
memblock_iter_t it;
struct memblock_iter it;
for_each_mem_region (&it, 0x0, UINTPTR_MAX) { ... }
EXAMPLE: to iterate through all memory regions between physical
addresses 0x40000 and 0x80000:
memblock_iter_t it;
struct memblock_iter it;
for_each_mem_region (&it, 0x40000, 0x80000) { ... }
*/
#define for_each_mem_range(i, p_start, p_end) \
@@ -75,7 +75,7 @@ extern "C" {
this iteration can be optionally constrained to a given region.
@param i the iterator. this should be a pointer of type memblock_iter_t.
@param i the iterator. this should be a pointer of type struct memblock_iter.
for each iteration, this structure will be filled with details about
the current memory region.
@param p_start the lower bound of the memory region to iterate through.
@@ -85,14 +85,14 @@ extern "C" {
EXAMPLE: to iterate through all reserved memory regions (with no bounds):
memblock_iter_t it;
struct memblock_iter it;
for_each_reserved_mem_region (&it, 0x0, UINTPTR_MAX) { ... }
EXAMPLE: to iterate through all reserved memory regions between physical
addresses 0x40000 and 0x80000:
memblock_iter_t it;
struct memblock_iter it;
for_each_reserved_mem_region (&it, 0x40000, 0x80000) { ... }
*/
#define for_each_reserved_mem_range(i, p_start, p_end) \
@@ -106,7 +106,7 @@ extern "C" {
this iteration can be optionally constrained to a given region.
@param i the iterator. this should be a pointer of type memblock_iter_t.
@param i the iterator. this should be a pointer of type struct memblock_iter.
for each iteration, this structure will be filled with details about
the current memory region.
@param p_start the lower bound of the memory region to iterate through.
@@ -128,7 +128,7 @@ extern "C" {
the following call:
memblock_iter_t it;
struct memblock_iter it;
for_each_free_mem_range (&it, 0x0, UINTPTR_MAX) { ... }
would iterate through the following sequence of free memory ranges:
@@ -143,7 +143,7 @@ extern "C" {
typedef uint64_t memblock_index_t;
typedef enum memblock_region_status {
enum memblock_region_status {
/* Used in memblock.memory regions, indicates that the memory region exists */
MEMBLOCK_MEMORY = 0,
/* Used in memblock.reserved regions, indicates that the memory region was reserved
@@ -152,27 +152,27 @@ typedef enum memblock_region_status {
/* Used in memblock.reserved regions, indicates that the memory region was reserved
* by a call to memblock_reserve() */
MEMBLOCK_RESERVED,
} memblock_region_status_t;
};
typedef struct memblock_region {
struct memblock_region {
/* the status of the memory region (free, reserved, allocated, etc) */
memblock_region_status_t status;
enum memblock_region_status status;
/* the address of the first byte that makes up the region */
phys_addr_t base;
/* the address of the last byte that makes up the region */
phys_addr_t limit;
} memblock_region_t;
};
/* buffer of memblock regions, all of which are the same type
(memory, reserved, etc) */
typedef struct memblock_type {
struct memblock_type {
struct memblock_region *regions;
unsigned int count;
unsigned int max;
const char *name;
} memblock_type_t;
};
typedef struct memblock {
struct memblock {
/* bounds of the memory region that can be used by memblock_alloc()
both of these are virtual addresses */
uintptr_t m_alloc_start, m_alloc_end;
@@ -183,19 +183,19 @@ typedef struct memblock {
struct memblock_type memory;
struct memblock_type reserved;
} memblock_t;
};
typedef struct memblock_iter {
struct memblock_iter {
memblock_index_t __idx;
phys_addr_t it_base;
phys_addr_t it_limit;
memblock_region_status_t it_status;
} memblock_iter_t;
enum memblock_region_status it_status;
};
/* global memblock state. */
extern memblock_t memblock;
extern struct memblock memblock;
extern int __next_mem_range(memblock_iter_t *it);
extern int __next_mem_range(struct memblock_iter *it);
/* initialise the global memblock state.
this function must be called before any other memblock functions can be used.
@@ -319,8 +319,8 @@ extern phys_addr_t memblock_virt_to_phys(void *p);
*/
extern void *memblock_phys_to_virt(phys_addr_t p);
extern void __next_memory_region(memblock_iter_t *it, \
memblock_type_t *type_a, memblock_type_t *type_b,
extern void __next_memory_region(struct memblock_iter *it, \
struct memblock_type *type_a, struct memblock_type *type_b,
phys_addr_t start, phys_addr_t end);
#ifdef __cplusplus

View File

@@ -16,11 +16,11 @@ extern "C" {
struct object;
struct object_attrib;
typedef enum object_type_flags {
enum object_type_flags {
OBJTYPE_INIT = 0x01u,
} object_type_flags_t;
};
typedef struct object_ops {
struct object_ops {
kern_status_t(*open)(struct object *obj);
kern_status_t(*close)(struct object *obj);
kern_status_t(*destroy)(struct object *obj);
@@ -30,64 +30,62 @@ typedef struct object_ops {
kern_status_t(*get_at)(struct object *obj, size_t at, struct object **out);
kern_status_t(*read_attrib)(struct object *obj, struct object_attrib *attrib, char *out, size_t max, size_t *r);
kern_status_t(*write_attrib)(struct object *obj, struct object_attrib *attrib, const char *s, size_t len, size_t *r);
} object_ops_t;
};
typedef struct object_attrib {
struct object_attrib {
char *a_name;
queue_entry_t a_list;
} object_attrib_t;
struct queue_entry a_list;
};
typedef struct object_type {
object_type_flags_t ob_flags;
struct object_type {
enum object_type_flags ob_flags;
char ob_name[32];
unsigned int ob_size;
vm_cache_t ob_cache;
queue_entry_t ob_list;
queue_t ob_attrib;
object_ops_t ob_ops;
} object_type_t;
struct vm_cache ob_cache;
struct queue_entry ob_list;
struct queue ob_attrib;
struct object_ops ob_ops;
};
typedef struct object {
struct object {
uint32_t ob_magic;
object_type_t *ob_type;
struct object_type *ob_type;
spin_lock_t ob_lock;
unsigned int ob_refcount;
unsigned int ob_handles;
queue_t ob_attrib;
queue_entry_t ob_list;
} __aligned(sizeof(long)) object_t;
typedef struct object_namespace object_namespace_t;
struct queue ob_attrib;
struct queue_entry ob_list;
} __aligned(sizeof(long));
extern kern_status_t object_bootstrap(void);
extern kern_status_t object_type_register(object_type_t *p);
extern kern_status_t object_type_unregister(object_type_t *p);
extern kern_status_t object_type_register(struct object_type *p);
extern kern_status_t object_type_unregister(struct object_type *p);
extern object_namespace_t *global_namespace(void);
extern object_namespace_t *object_namespace_create(void);
extern kern_status_t object_namespace_get_object(object_namespace_t *ns, const char *path, object_t **out);
extern kern_status_t object_publish(object_namespace_t *ns, const char *path, object_t *obj);
extern kern_status_t object_unpublish(object_namespace_t *ns, object_t *obj);
extern struct object_namespace *global_namespace(void);
extern struct object_namespace *object_namespace_create(void);
extern kern_status_t object_namespace_get_object(struct object_namespace *ns, const char *path, struct object **out);
extern kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj);
extern kern_status_t object_unpublish(struct object_namespace *ns, struct object *obj);
extern object_t *object_create(object_type_t *type);
extern object_t *object_ref(object_t *obj);
extern void object_deref(object_t *obj);
extern void object_lock(object_t *obj, unsigned long *flags);
extern void object_unlock(object_t *obj, unsigned long flags);
extern void *object_data(object_t *obj);
extern object_t *object_header(void *p);
static inline kern_status_t object_get(const char *path, object_t **out)
extern struct object *object_create(struct object_type *type);
extern struct object *object_ref(struct object *obj);
extern void object_deref(struct object *obj);
extern void object_lock(struct object *obj, unsigned long *flags);
extern void object_unlock(struct object *obj, unsigned long flags);
extern void *object_data(struct object *obj);
extern struct object *object_header(void *p);
static inline kern_status_t object_get(const char *path, struct object **out)
{
return object_namespace_get_object(global_namespace(), path, out);
}
extern kern_status_t object_get_child_named(object_t *obj, const char *name, object_t **out);
extern kern_status_t object_get_child_at(object_t *obj, size_t at, object_t **out);
extern kern_status_t object_query_name(object_t *obj, char name[OBJECT_NAME_MAX]);
extern kern_status_t object_get_child_named(struct object *obj, const char *name, struct object **out);
extern kern_status_t object_get_child_at(struct object *obj, size_t at, struct object **out);
extern kern_status_t object_query_name(struct object *obj, char name[OBJECT_NAME_MAX]);
extern object_t *set_create(const char *name);
extern kern_status_t set_add_object(object_t *set, object_t *obj);
extern kern_status_t set_remove_object(object_t *set, object_t *obj);
extern bool object_is_set(object_t *obj);
extern struct object *set_create(const char *name);
extern kern_status_t set_add_object(struct object *set, struct object *obj);
extern kern_status_t set_remove_object(struct object *set, struct object *obj);
extern bool object_is_set(struct object *obj);
extern void init_set_objects(void);
extern void init_global_namespace(void);

View File

@@ -17,9 +17,9 @@ extern "C" {
typedef ml_pmap_t pmap_t;
typedef ml_pfn_t pfn_t;
typedef enum pmap_flags {
enum pmap_flags {
PMAP_HUGEPAGE = 0x01u,
} pmap_flags_t;
};
extern void pmap_bootstrap(void);
extern pmap_t get_kernel_pmap(void);
@@ -28,8 +28,8 @@ extern pmap_t pmap_create(void);
extern void pmap_destroy(pmap_t pmap);
extern void pmap_switch(pmap_t pmap);
extern kern_status_t pmap_add(pmap_t pmap, void *p, pfn_t pfn, vm_prot_t prot, pmap_flags_t flags);
extern kern_status_t pmap_add_block(pmap_t pmap, void *p, pfn_t pfn, size_t len, vm_prot_t prot, pmap_flags_t flags);
extern kern_status_t pmap_add(pmap_t pmap, void *p, pfn_t pfn, enum vm_prot prot, enum pmap_flags flags);
extern kern_status_t pmap_add_block(pmap_t pmap, void *p, pfn_t pfn, size_t len, enum vm_prot prot, enum pmap_flags flags);
extern kern_status_t pmap_remove(pmap_t pmap, void *p);
extern kern_status_t pmap_remove_range(pmap_t pmap, void *p, size_t len);

View File

@@ -7,7 +7,7 @@
extern "C" {
#endif
extern void early_printk_init(console_t *con);
extern void early_printk_init(struct console *con);
extern int printk(const char *format, ...);
#ifdef __cplusplus

View File

@@ -10,8 +10,8 @@ extern "C" {
#define QUEUE_CONTAINER(t, m, v) ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0))
#define QUEUE_INIT ((queue_t){ .q_first = NULL, .q_last = NULL })
#define QUEUE_ENTRY_INIT ((queue_entry_t){ .qe_next = NULL, .qe_prev = NULL })
#define QUEUE_INIT ((struct queue){ .q_first = NULL, .q_last = NULL })
#define QUEUE_ENTRY_INIT ((struct queue_entry){ .qe_next = NULL, .qe_prev = NULL })
#define queue_foreach(iter_type, iter_name, queue_name, node_member) \
for (iter_type *iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_first(queue_name)); \
@@ -23,37 +23,37 @@ extern "C" {
iter_name; \
iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_prev(&((iter_name)->node_member))))
typedef struct queue_entry {
struct queue_entry {
struct queue_entry *qe_next;
struct queue_entry *qe_prev;
} queue_entry_t;
};
typedef struct queue {
queue_entry_t *q_first;
queue_entry_t *q_last;
} queue_t;
struct queue {
struct queue_entry *q_first;
struct queue_entry *q_last;
};
static inline void queue_init(queue_t *q) { memset(q, 0x00, sizeof *q); }
static inline bool queue_empty(queue_t *q) { return q->q_first == NULL; }
static inline void queue_init(struct queue *q) { memset(q, 0x00, sizeof *q); }
static inline bool queue_empty(struct queue *q) { return q->q_first == NULL; }
static inline queue_entry_t *queue_first(queue_t *q) { return q->q_first; }
static inline queue_entry_t *queue_last(queue_t *q) { return q->q_last; }
static inline queue_entry_t *queue_next(queue_entry_t *entry) { return entry->qe_next; }
static inline queue_entry_t *queue_prev(queue_entry_t *entry) { return entry->qe_prev; }
static inline struct queue_entry *queue_first(struct queue *q) { return q->q_first; }
static inline struct queue_entry *queue_last(struct queue *q) { return q->q_last; }
static inline struct queue_entry *queue_next(struct queue_entry *entry) { return entry->qe_next; }
static inline struct queue_entry *queue_prev(struct queue_entry *entry) { return entry->qe_prev; }
extern size_t queue_length(queue_t *q);
extern size_t queue_length(struct queue *q);
extern void queue_insert_before(queue_t *q, queue_entry_t *entry, queue_entry_t *before);
extern void queue_insert_after(queue_t *q, queue_entry_t *entry, queue_entry_t *after);
extern void queue_insert_before(struct queue *q, struct queue_entry *entry, struct queue_entry *before);
extern void queue_insert_after(struct queue *q, struct queue_entry *entry, struct queue_entry *after);
extern void queue_push_front(queue_t *q, queue_entry_t *entry);
extern void queue_push_back(queue_t *q, queue_entry_t *entry);
extern void queue_push_front(struct queue *q, struct queue_entry *entry);
extern void queue_push_back(struct queue *q, struct queue_entry *entry);
extern queue_entry_t *queue_pop_front(queue_t *q);
extern queue_entry_t *queue_pop_back(queue_t *q);
extern struct queue_entry *queue_pop_front(struct queue *q);
extern struct queue_entry *queue_pop_back(struct queue *q);
extern void queue_delete(queue_t *q, queue_entry_t *entry);
extern void queue_delete_all(queue_t *q);
extern void queue_delete(struct queue *q, struct queue_entry *entry);
extern void queue_delete_all(struct queue *q);
#ifdef __cplusplus
}

View File

@@ -15,91 +15,91 @@
extern "C" {
#endif
typedef enum task_state {
enum task_state {
TASK_RUNNING,
TASK_STOPPED,
} task_state_t;
};
typedef enum thread_state {
enum thread_state {
THREAD_READY = 1,
THREAD_SLEEPING = 2,
THREAD_STOPPED = 3,
} thread_state_t;
};
typedef enum thread_flags {
enum thread_flags {
THREAD_F_NEED_RESCHED = 0x01u,
THREAD_F_NO_PREEMPT = 0x02u,
} thread_flags_t;
};
typedef enum sched_priority {
PRIO_IDLE = 4,
PRIO_SUBNORMAL = 6,
PRIO_NORMAL = 10,
PRIO_SUPERNORMAL = 14,
PRIO_HIGH = 18,
PRIO_REALTIME = 24,
} sched_priority_t;
enum sched_priority {
PRIO_IDLE = 4,
PRIO_SUBNORMAL = 6,
PRIO_NORMAL = 10,
PRIO_SUPERNORMAL = 14,
PRIO_HIGH = 18,
PRIO_REALTIME = 24,
};
typedef struct task {
struct task {
struct task *t_parent;
unsigned int t_id;
task_state_t t_state;
enum task_state t_state;
char t_name[TASK_NAME_MAX];
pmap_t t_pmap;
btree_node_t t_tasklist;
queue_t t_threads;
queue_t t_children;
} task_t;
struct btree_node t_tasklist;
struct queue t_threads;
struct queue t_children;
};
typedef struct thread {
thread_state_t tr_state : 8;
thread_flags_t tr_flags : 8;
task_t *tr_parent;
struct thread {
enum thread_state tr_state : 8;
enum thread_flags tr_flags : 8;
struct task *tr_parent;
unsigned int tr_id;
unsigned int tr_prio;
queue_entry_t tr_threads;
queue_entry_t tr_rqentry;
struct queue_entry tr_threads;
struct queue_entry tr_rqentry;
void *tr_kstack;
} thread_t;
};
typedef struct runqueue {
queue_t rq_queues[PRIO_MAX];
struct runqueue {
struct queue rq_queues[PRIO_MAX];
uint32_t rq_readybits;
spin_lock_t rq_lock;
} runqueue_t;
};
extern kern_status_t sched_init(void);
extern void schedule(void);
extern void preempt_disable(void);
extern void preempt_enable(void);
extern void runqueue_init(runqueue_t *rq);
extern void runqueue_init(struct runqueue *rq);
extern task_t *task_alloc(void);
static inline task_t *task_ref(task_t *task) { return (task_t *)object_data(object_ref(object_header(task))); }
static inline void task_deref(task_t *task) { object_deref(object_header(task)); }
extern task_t *task_from_pid(unsigned int pid);
extern task_t *kernel_task(void);
extern struct task *task_alloc(void);
static inline struct task *task_ref(struct task *task) { return (struct task *)object_data(object_ref(object_header(task))); }
static inline void task_deref(struct task *task) { object_deref(object_header(task)); }
extern struct task *task_from_pid(unsigned int pid);
extern struct task *kernel_task(void);
extern bool need_resched(void);
extern task_t *current_task(void);
extern thread_t *current_thread(void);
extern struct task *current_task(void);
extern struct thread *current_thread(void);
static inline void task_lock_irqsave(task_t *task, unsigned long *flags)
static inline void task_lock_irqsave(struct task *task, unsigned long *flags)
{
object_lock(object_header(task), flags);
}
static inline void task_unlock_irqrestore(task_t *task, unsigned long flags)
static inline void task_unlock_irqrestore(struct task *task, unsigned long flags)
{
object_unlock(object_header(task), flags);
}
extern thread_t *thread_alloc(void);
extern struct thread *thread_alloc(void);
#ifdef __cplusplus
}

View File

@@ -13,9 +13,9 @@
buffered user input.
A TTY object is split into 2 parts:
- tty_t: This represents the terminal session, and tracks things like the cursor
- struct tty: This represents the terminal session, and tracks things like the cursor
position, input buffer, flags, etc.
- tty_driver_t: This is a set of function callbacks that the TTY can use to
- struct tty_driver: This is a set of function callbacks that the TTY can use to
manipulate the output device. This could represent a char-based framebuffer
device, a serial port, etc.
*/
@@ -27,66 +27,66 @@ extern "C" {
/* opaque context pointer for use by the tty driver */
typedef void *tty_driver_ctx_t;
typedef enum tty_driver_type {
enum tty_driver_type {
/* For TTYs operating on simple IO devices like serial ports.
Allows writing characters, receiving characters, and not much else. */
TTY_DRIVER_SIMPLE,
/* For TTYs operating on more capable display interfaces.
Allows putting characters at arbitrary locations, scrolling, etc */
TTY_DRIVER_FULL,
} tty_driver_type_t;
};
/* TTY cursor status. The extra cursor styles are just for completeness,
the important one to support (if possible), is TTY_CURSOR_NONE.
The others can be interpreted as "just turn on a cursor of any style". */
typedef enum tty_cursor {
enum tty_cursor {
TTY_CURSOR_ULINE,
TTY_CURSOR_BLOCK,
TTY_CURSOR_NONE,
} tty_cursor_t;
};
/* direction to use for scrolling. The important one to support is
TTY_SCROLL_DOWN for when output overflows the display */
typedef enum tty_scroll_dir {
enum tty_scroll_dir {
TTY_SCROLL_DOWN,
TTY_SCROLL_UP,
} tty_scroll_dir_t;
};
/* character attribute. this could be as simple as VGA's 16-colour palette
plus an extra bit for bright, or a full 24-bit RGB value with bold and underline
support, depending on what the driver supports. */
typedef uint64_t tty_attrib_t;
typedef struct tty_driver {
struct tty_driver {
char tty_name[16];
tty_driver_type_t tty_type;
queue_entry_t tty_list;
enum tty_driver_type tty_type;
struct queue_entry tty_list;
void (*tty_init)(tty_driver_ctx_t *ctx);
void (*tty_deinit)(tty_driver_ctx_t ctx);
void (*tty_clear)(tty_driver_ctx_t ctx, int x, int y, int width, int height);
void (*tty_putc)(tty_driver_ctx_t ctx, int c, int xpos, int ypos, tty_attrib_t attrib);
void (*tty_set_cursor)(tty_driver_ctx_t ctx, tty_cursor_t cur);
void (*tty_set_cursor)(tty_driver_ctx_t ctx, enum tty_cursor cur);
void (*tty_move_cursor)(tty_driver_ctx_t ctx, int x, int y);
void (*tty_scroll)(tty_driver_ctx_t ctx, tty_scroll_dir_t dir, int lines);
} tty_driver_t;
void (*tty_scroll)(tty_driver_ctx_t ctx, enum tty_scroll_dir dir, int lines);
};
typedef struct tty {
struct tty {
int tty_xcur, tty_ycur;
unsigned int tty_iflag, tty_oflag, tty_lflag;
tty_driver_ctx_t tty_dctx;
const tty_driver_t *tty_driver;
} tty_t;
const struct tty_driver *tty_driver;
};
extern kern_status_t tty_driver_register(tty_driver_t *drv);
extern kern_status_t tty_driver_unregister(tty_driver_t *drv);
extern kern_status_t tty_driver_register(struct tty_driver *drv);
extern kern_status_t tty_driver_unregister(struct tty_driver *drv);
extern tty_t *tty_create(void);
extern void tty_destroy(tty_t *tty);
extern struct tty *tty_create(void);
extern void tty_destroy(struct tty *tty);
extern int tty_read(tty_t *tty, char *s, unsigned long len);
extern int tty_write(tty_t *tty, const char *s, unsigned long len);
extern int tty_read(struct tty *tty, char *s, unsigned long len);
extern int tty_write(struct tty *tty, const char *s, unsigned long len);
#ifdef __cplusplus
}

View File

@@ -27,34 +27,34 @@ extern "C" {
#define VM_PAGE_IS_FREE(pg) (((pg)->p_flags & (VM_PAGE_RESERVED | VM_PAGE_ALLOC)) == 0)
#define vm_page_foreach(pg, i) \
for (vm_page_t *i = (pg); i; i = vm_page_get_next_tail(i))
for (struct vm_page *i = (pg); i; i = vm_page_get_next_tail(i))
typedef phys_addr_t vm_alignment_t;
typedef unsigned int vm_node_id_t;
typedef struct vm_object {
struct vm_object {
unsigned int reserved;
} vm_object_t;
};
typedef enum vm_model {
enum vm_model {
VM_MODEL_FLAT = 1,
VM_MODEL_SPARSE,
} vm_model_t;
};
typedef enum vm_prot {
enum vm_prot {
VM_PROT_READ = 0x01u,
VM_PROT_WRITE = 0x02u,
VM_PROT_EXEC = 0x04u,
VM_PROT_USER = 0x08u,
VM_PROT_SVR = 0x10u,
} vm_prot_t;
};
typedef enum vm_flags {
enum vm_flags {
VM_NORMAL = 0x00u,
VM_GET_DMA = 0x01u,
} vm_flags_t;
};
typedef enum vm_zone_id {
enum vm_zone_id {
/* NOTE that these are used as indices into the node_zones array in vm/zone.c
they need to be continuous, and must start at 0! */
VM_ZONE_DMA = 0u,
@@ -62,9 +62,9 @@ typedef enum vm_zone_id {
VM_ZONE_HIGHMEM = 2u,
VM_ZONE_MIN = VM_ZONE_DMA,
VM_ZONE_MAX = VM_ZONE_HIGHMEM,
} vm_zone_id_t;
};
typedef enum vm_page_order {
enum vm_page_order {
VM_PAGE_4K = 0u,
VM_PAGE_8K,
VM_PAGE_16K,
@@ -82,7 +82,7 @@ typedef enum vm_page_order {
VM_PAGE_64M,
VM_PAGE_128M,
/* vm_page_t only has 4 bits to store the page order with.
/* struct vm_page only has 4 bits to store the page order with.
the maximum order that can be stored in 4 bits is 15 (VM_PAGE_128M)
to use any of the page orders listed here, this field
will have to be expanded. */
@@ -95,9 +95,9 @@ typedef enum vm_page_order {
VM_PAGE_16G,
VM_PAGE_32G,
VM_PAGE_64G,
} vm_page_order_t;
};
typedef enum vm_page_flags {
enum vm_page_flags {
/* page is reserved (probably by a call to memblock_reserve()) and cannot be
returned by any allocation function */
VM_PAGE_RESERVED = 0x01u,
@@ -107,52 +107,52 @@ typedef enum vm_page_flags {
VM_PAGE_HEAD = 0x04u,
/* page is part of a huge-page */
VM_PAGE_HUGE = 0x08u,
} vm_page_flags_t;
};
typedef enum vm_memory_region_status {
enum vm_memory_region_status {
VM_REGION_FREE = 0x01u,
VM_REGION_RESERVED = 0x02u,
} vm_memory_region_status_t;
};
typedef enum vm_cache_flags {
enum vm_cache_flags {
VM_CACHE_OFFSLAB = 0x01u,
VM_CACHE_DMA = 0x02u
} vm_cache_flags_t;
};
typedef struct vm_zone_descriptor {
vm_zone_id_t zd_id;
struct vm_zone_descriptor {
enum vm_zone_id zd_id;
vm_node_id_t zd_node;
const char zd_name[32];
phys_addr_t zd_base;
phys_addr_t zd_limit;
} vm_zone_descriptor_t;
};
typedef struct vm_zone {
vm_zone_descriptor_t z_info;
struct vm_zone {
struct vm_zone_descriptor z_info;
spin_lock_t z_lock;
queue_t z_free_pages[VM_MAX_PAGE_ORDERS];
struct queue z_free_pages[VM_MAX_PAGE_ORDERS];
unsigned long z_size;
} vm_zone_t;
};
typedef struct vm_pg_data {
vm_zone_t pg_zones[VM_MAX_ZONES];
} vm_pg_data_t;
struct vm_pg_data {
struct vm_zone pg_zones[VM_MAX_ZONES];
};
typedef struct vm_region {
vm_memory_region_status_t r_status;
struct vm_region {
enum vm_memory_region_status r_status;
phys_addr_t r_base;
phys_addr_t r_limit;
} vm_region_t;
};
typedef struct vm_cache {
struct vm_cache {
const char *c_name;
vm_cache_flags_t c_flags;
queue_entry_t c_list;
enum vm_cache_flags c_flags;
struct queue_entry c_list;
queue_t c_slabs_full;
queue_t c_slabs_partial;
queue_t c_slabs_empty;
struct queue c_slabs_full;
struct queue c_slabs_partial;
struct queue c_slabs_empty;
spin_lock_t c_lock;
@@ -160,7 +160,7 @@ typedef struct vm_cache {
unsigned int c_obj_count;
/* the size of object kept in the cache */
unsigned int c_obj_size;
/* combined size of vm_slab_t and the freelist */
/* combined size of struct vm_slab and the freelist */
unsigned int c_hdr_size;
/* power of 2 alignment for objects returned from the cache */
unsigned int c_align;
@@ -170,12 +170,12 @@ typedef struct vm_cache {
unsigned int c_stride;
/* size of page used for slabs */
unsigned int c_page_order;
} vm_cache_t;
};
typedef struct vm_slab {
vm_cache_t *s_cache;
/* queue entry for vm_cache_t.c_slabs_* */
queue_entry_t s_list;
struct vm_slab {
struct vm_cache *s_cache;
/* queue entry for struct vm_cache.c_slabs_* */
struct queue_entry s_list;
/* pointer to the first object slot. */
void *s_objects;
/* the number of objects allocated on the slab. */
@@ -193,9 +193,9 @@ typedef struct vm_slab {
this is commented as it as flexible arrays are not supported in c++.
*/
//unsigned int s_freelist[];
} vm_slab_t;
};
typedef struct vm_page {
struct vm_page {
/* order of the page block that this page belongs too */
uint32_t p_order : 4;
/* the id of the NUMA node that this page belongs to */
@@ -214,82 +214,82 @@ typedef struct vm_page {
some examples:
- the buddy allocator uses this to maintain its per-zone free-page lists.
*/
queue_entry_t p_list;
struct queue_entry p_list;
/* owner-specific data */
union {
vm_slab_t *p_slab;
struct vm_slab *p_slab;
};
} __attribute__((aligned(2 * sizeof(unsigned long)))) vm_page_t;
} __attribute__((aligned(2 * sizeof(unsigned long))));
/* represents a sector of memory, containing its own array of vm_pages.
this struct is used under the sparse memory model, instead of the
global vm_page array */
typedef struct vm_sector {
struct vm_sector {
/* sector size. this must be a power of 2.
all sectors in the system have the same size. */
vm_page_order_t s_size;
enum vm_page_order s_size;
/* PFN of the first page contained in s_pages.
to find the PFN of any page contained within s_pages,
simply add its offset within the array to s_first_pfn */
size_t s_first_pfn;
/* array of pages contained in this sector */
vm_page_t *s_pages;
} vm_sector_t;
struct vm_page *s_pages;
};
extern kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones);
extern vm_model_t vm_memory_model(void);
extern void vm_set_memory_model(vm_model_t model);
extern kern_status_t vm_bootstrap(const struct vm_zone_descriptor *zones, size_t nr_zones);
extern enum vm_model vm_memory_model(void);
extern void vm_set_memory_model(enum vm_model model);
extern vm_pg_data_t *vm_pg_data_get(vm_node_id_t node);
extern struct vm_pg_data *vm_pg_data_get(vm_node_id_t node);
extern phys_addr_t vm_virt_to_phys(void *p);
extern void *vm_phys_to_virt(phys_addr_t p);
extern void vm_page_init_array();
extern vm_page_t *vm_page_get(phys_addr_t addr);
extern phys_addr_t vm_page_get_paddr(vm_page_t *pg);
extern vm_zone_t *vm_page_get_zone(vm_page_t *pg);
extern void *vm_page_get_vaddr(vm_page_t *pg);
extern size_t vm_page_get_pfn(vm_page_t *pg);
extern size_t vm_page_order_to_bytes(vm_page_order_t order);
extern size_t vm_page_order_to_pages(vm_page_order_t order);
extern vm_alignment_t vm_page_order_to_alignment(vm_page_order_t order);
extern vm_page_t *vm_page_alloc(vm_page_order_t order, vm_flags_t flags);
extern void vm_page_free(vm_page_t *pg);
extern struct vm_page *vm_page_get(phys_addr_t addr);
extern phys_addr_t vm_page_get_paddr(struct vm_page *pg);
extern struct vm_zone *vm_page_get_zone(struct vm_page *pg);
extern void *vm_page_get_vaddr(struct vm_page *pg);
extern size_t vm_page_get_pfn(struct vm_page *pg);
extern size_t vm_page_order_to_bytes(enum vm_page_order order);
extern size_t vm_page_order_to_pages(enum vm_page_order order);
extern vm_alignment_t vm_page_order_to_alignment(enum vm_page_order order);
extern struct vm_page *vm_page_alloc(enum vm_page_order order, enum vm_flags flags);
extern void vm_page_free(struct vm_page *pg);
extern int vm_page_split(vm_page_t *pg, vm_page_t **a, vm_page_t **b);
extern vm_page_t *vm_page_merge(vm_page_t *a, vm_page_t *b);
extern vm_page_t *vm_page_get_buddy(vm_page_t *pg);
extern vm_page_t *vm_page_get_next_tail(vm_page_t *pg);
extern int vm_page_split(struct vm_page *pg, struct vm_page **a, struct vm_page **b);
extern struct vm_page *vm_page_merge(struct vm_page *a, struct vm_page *b);
extern struct vm_page *vm_page_get_buddy(struct vm_page *pg);
extern struct vm_page *vm_page_get_next_tail(struct vm_page *pg);
extern size_t vm_bytes_to_pages(size_t bytes);
extern void vm_zone_init(vm_zone_t *z, const vm_zone_descriptor_t *zone_info);
extern vm_page_t *vm_zone_alloc_page(vm_zone_t *z, vm_page_order_t order, vm_flags_t flags);
extern void vm_zone_free_page(vm_zone_t *z, vm_page_t *pg);
extern void vm_zone_init(struct vm_zone *z, const struct vm_zone_descriptor *zone_info);
extern struct vm_page *vm_zone_alloc_page(struct vm_zone *z, enum vm_page_order order, enum vm_flags flags);
extern void vm_zone_free_page(struct vm_zone *z, struct vm_page *pg);
extern vm_cache_t *vm_cache_create(const char *name, size_t objsz, vm_cache_flags_t flags);
extern void vm_cache_init(vm_cache_t *cache);
extern void vm_cache_destroy(vm_cache_t *cache);
extern void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags);
extern void vm_cache_free(vm_cache_t *cache, void *p);
extern struct vm_cache *vm_cache_create(const char *name, size_t objsz, enum vm_cache_flags flags);
extern void vm_cache_init(struct vm_cache *cache);
extern void vm_cache_destroy(struct vm_cache *cache);
extern void *vm_cache_alloc(struct vm_cache *cache, enum vm_flags flags);
extern void vm_cache_free(struct vm_cache *cache, void *p);
extern void kmalloc_init(void);
extern void *kmalloc(size_t count, vm_flags_t flags);
extern void *kzalloc(size_t count, vm_flags_t flags);
extern void *kmalloc(size_t count, enum vm_flags flags);
extern void *kzalloc(size_t count, enum vm_flags flags);
extern void kfree(void *p);
/* Flat memory model functions */
extern void vm_flat_init(void);
extern vm_page_t *vm_page_get_flat(phys_addr_t addr);
extern size_t vm_page_get_pfn_flat(vm_page_t *pg);
extern struct vm_page *vm_page_get_flat(phys_addr_t addr);
extern size_t vm_page_get_pfn_flat(struct vm_page *pg);
/* Sparse memory model functions */
extern void vm_sparse_init(void);
extern vm_page_t *vm_page_get_sparse(phys_addr_t addr);
extern size_t vm_page_get_pfn_sparse(vm_page_t *pg);
extern struct vm_page *vm_page_get_sparse(phys_addr_t addr);
extern size_t vm_page_get_pfn_sparse(struct vm_page *pg);
#ifdef __cplusplus
}