summaryrefslogtreecommitdiff
path: root/kern/init.h
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-07-13 20:05:07 +0200
committerRichard Braun <rbraun@sceen.net>2017-07-13 20:05:07 +0200
commitcacd797c0c1825301f21aab18a7ce2c410d14535 (patch)
tree3df3ef3ceb452732d9feb7aaf1b71fd4bd138333 /kern/init.h
parent634e07dad2dd596610908f7cdd6b82fcf0f35d0a (diff)
kern/init: introduce initialization operations
Init operations are a mechanism to run initilization functions based on their dependencies. They are meant to replace the imperatively declared static order currently used.
Diffstat (limited to 'kern/init.h')
-rw-r--r--kern/init.h68
1 files changed, 67 insertions, 1 deletions
diff --git a/kern/init.h b/kern/init.h
index 62fecf40..d15d9503 100644
--- a/kern/init.h
+++ b/kern/init.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012 Richard Braun.
+ * Copyright (c) 2010-2017 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,6 +13,11 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Init sections and operations.
+ *
+ * TODO Make the x86 linker script use macros from this header.
*/
#ifndef _KERN_INIT_H
@@ -25,8 +30,15 @@
#define INIT_SECTION .init.text
#define INIT_DATA_SECTION .init.data
+/*
+ * This section must only contain init operation structures, and must be
+ * located inside the .init section.
+ */
+#define INIT_OPS_SECTION .init.ops
+
#ifndef __ASSEMBLER__
+#include <kern/error.h>
#include <kern/macros.h>
#define __init __section(QUOTE(INIT_SECTION))
@@ -38,6 +50,60 @@
extern char _init;
extern char _init_end;
+/*
+ * Type for initialization operation functions.
+ */
+typedef int (*init_op_fn_t)(void);
+
+#include <kern/init_i.h>
+
+/*
+ * Forge an init operation declaration.
+ */
+#define INIT_OP_DECLARE(fn) extern struct init_op INIT_OP(fn)
+
+/*
+ * Foge an entry suitable as an init operation dependency.
+ *
+ * If a dependency isn't required, it's still used to determine run
+ * order, but its result is ignored, and the operation depending on it
+ * behaves as if that dependency succeeded.
+ */
+#define INIT_OP_DEP(fn, required) { &INIT_OP(fn), required }
+
+/*
+ * Init operation definition macro.
+ *
+ * This macro is used to define a structure named after the given function.
+ * Init operations are placed in a specific section which doesn't contain
+ * any other object type, making it a system-wide array of init operations.
+ * There is no need to actively register init operations; this module finds
+ * them all from their section. Dependencies are given as a variable-length
+ * argument list of entries built with the INIT_OP_DEP() macro.
+ */
+#define INIT_OP_DEFINE(_fn, ...) \
+ static struct init_op_dep INIT_OP_DEPS(_fn)[] __initdata = { \
+ __VA_ARGS__ \
+ }; \
+ \
+ struct init_op INIT_OP(_fn) __initop = { \
+ .name = QUOTE(_fn), \
+ .fn = _fn, \
+ .deps = INIT_OP_DEPS(_fn), \
+ .error = ERROR_AGAIN, \
+ .state = INIT_OP_STATE_UNLINKED, \
+ .nr_deps = ARRAY_SIZE(INIT_OP_DEPS(_fn)), \
+ .nr_parents = 0, \
+ }
+
+/*
+ * Initialize the init module.
+ *
+ * Scan the section containing init operations, resolve all dependencies,
+ * and run operations in an appropriate order.
+ */
+void init_setup(void);
+
#endif /* __ASSEMBLER__ */
#endif /* _KERN_INIT_H */