kernel: don't use typedef for enums or non-opaque structs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user