diff options
author | Richard Braun <rbraun@sceen.net> | 2017-07-13 20:05:07 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-07-13 20:05:07 +0200 |
commit | cacd797c0c1825301f21aab18a7ce2c410d14535 (patch) | |
tree | 3df3ef3ceb452732d9feb7aaf1b71fd4bd138333 /kern/init.h | |
parent | 634e07dad2dd596610908f7cdd6b82fcf0f35d0a (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.h | 68 |
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 */ |