init.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) 2010-2017 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. *
  18. * Init sections and operations.
  19. */
  20. #ifndef KERN_INIT_H
  21. #define KERN_INIT_H
  22. /*
  23. * These sections should contain code and data which can be discarded once
  24. * kernel initialization is done.
  25. */
  26. #define INIT_SECTION .init.text
  27. #define INIT_DATA_SECTION .init.data
  28. /*
  29. * This section must only contain init operation structures, and must be
  30. * located inside the .init section.
  31. */
  32. #define INIT_OPS_SECTION .init.ops
  33. /*
  34. * Alignment is important to make sure initialization operations are
  35. * stored as a C array in the reserved init op section.
  36. */
  37. #define INIT_OP_ALIGN 64
  38. #ifndef __ASSEMBLER__
  39. #include <errno.h>
  40. #include <stdalign.h>
  41. #include <stdbool.h>
  42. #include <stddef.h>
  43. #include <kern/macros.h>
  44. #include <kern/slist_types.h>
  45. #define __init __section (QUOTE (INIT_SECTION))
  46. #define __initdata __section (QUOTE (INIT_DATA_SECTION))
  47. // Boundaries of the .init section.
  48. extern char _init;
  49. extern char _init_end;
  50. // Type for initialization operation functions.
  51. typedef int (*init_op_fn_t) (void);
  52. #define __initop __section(QUOTE(INIT_OPS_SECTION))
  53. #define INIT_OP_STATE_UNLINKED 0
  54. #define INIT_OP_STATE_PENDING 1
  55. #define INIT_OP_STATE_COMPLETE 2
  56. struct init_op
  57. {
  58. alignas (INIT_OP_ALIGN) struct slist_node list_node;
  59. struct slist_node stack_node;
  60. const char *name;
  61. init_op_fn_t fn;
  62. struct init_op_dep *deps;
  63. int error;
  64. unsigned char state;
  65. unsigned char nr_deps;
  66. unsigned char nr_parents;
  67. };
  68. struct init_op_dep
  69. {
  70. struct init_op *op;
  71. bool required;
  72. };
  73. #define INIT_OP_DEPS(fn) CONCAT (fn, _init_op_deps)
  74. #define INIT_OP(fn) CONCAT (fn, _init_op)
  75. // Forge an init operation declaration.
  76. #define INIT_OP_DECLARE(fn) extern struct init_op INIT_OP (fn)
  77. /*
  78. * Foge an entry suitable as an init operation dependency.
  79. *
  80. * If a dependency isn't required, it's still used to determine run
  81. * order, but its result is ignored, and the operation depending on it
  82. * behaves as if that dependency succeeded.
  83. */
  84. #define INIT_OP_DEP(fn, required) { &INIT_OP (fn), required }
  85. /*
  86. * Init operation definition macro.
  87. *
  88. * This macro is used to define a structure named after the given function.
  89. * Init operations are placed in a specific section which doesn't contain
  90. * any other object type, making it a system-wide array of init operations.
  91. * There is no need to actively register init operations; this module finds
  92. * them all from their section. Dependencies are given as a variable-length
  93. * argument list of entries built with the INIT_OP_DEP() macro.
  94. */
  95. #define INIT_OP_DEFINE(_fn, ...) \
  96. static struct init_op_dep INIT_OP_DEPS(_fn)[] __initdata = \
  97. { \
  98. __VA_ARGS__ \
  99. }; \
  100. \
  101. struct init_op INIT_OP(_fn) __initop __used = \
  102. { \
  103. .name = QUOTE (_fn), \
  104. .fn = _fn, \
  105. .deps = INIT_OP_DEPS (_fn), \
  106. .error = EAGAIN, \
  107. .state = INIT_OP_STATE_UNLINKED, \
  108. .nr_deps = ARRAY_SIZE (INIT_OP_DEPS (_fn)), \
  109. .nr_parents = 0, \
  110. }
  111. /*
  112. * Initialize the init module.
  113. *
  114. * Scan the section containing init operations, resolve all dependencies,
  115. * and run operations in an appropriate order.
  116. */
  117. void init_setup (void);
  118. #endif // __ASSEMBLER__
  119. #endif