The Pedigree Project 0.1
Module.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
85#ifndef MODULE_H
86#define MODULE_H
87#include "pedigree/kernel/compiler.h"
88#include "pedigree/kernel/utilities/utility.h"
89
90#include <config.h>
91
92#ifndef __cplusplus
93#include <stdbool.h>
94#endif
95
96typedef bool (*ModuleEntry)();
97typedef void (*ModuleExit)();
98
99#define MODULE_TAG 0xdeadbaba
100
102 uint32_t tag;
103 const char* name;
104 ModuleEntry entry;
105 ModuleExit exit;
106 const char** dependencies;
107 const char** opt_dependencies;
108 // False pins the module image for the kernel lifetime, even if entry fails.
109 bool unloadable;
110 // False rejects explicit unload while still permitting failure and shutdown cleanup.
111 bool runtimeUnloadable;
112} PACKED;
113
114#if STATIC_DRIVERS
115
116extern ModuleInfo* g_StaticDrivers[128];
117extern size_t g_StaticDriverN;
118
119class StaticDriverModule {
120 public:
121 StaticDriverModule(const char* name, ModuleEntry entry, ModuleExit exit, const char** deps,
122 bool unloadable, const char** opt_deps = nullptr)
123 : StaticDriverModule(name, entry, exit, deps, unloadable, opt_deps, unloadable) {}
124
125 StaticDriverModule(const char* name, ModuleEntry entry, ModuleExit exit, const char** deps,
126 bool unloadable, const char** opt_deps, bool runtimeUnloadable) {
127 info.tag = MODULE_TAG;
128 info.name = name;
129 info.entry = entry;
130 info.exit = exit;
131 info.dependencies = deps;
132 info.opt_dependencies = opt_deps;
133 info.unloadable = unloadable;
134 info.runtimeUnloadable = runtimeUnloadable;
135 g_StaticDrivers[g_StaticDriverN++] = &info;
136 }
137
138 ModuleInfo info;
139};
140
141class StaticDriverOptionalDependencies {
142 public:
143 StaticDriverOptionalDependencies(StaticDriverModule& module, const char** dependencies) {
144 module.info.opt_dependencies = dependencies;
145 }
146};
147
148#define MODULE_INFO2_FLAGS(unloadable, runtimeUnloadable, name, entry, exit, ...) \
149 static const char* __mod_deps[] = {__VA_ARGS__, 0}; \
150 static StaticDriverModule __module(name, entry, exit, __mod_deps, unloadable, nullptr, \
151 runtimeUnloadable);
152
153#define MODULE_INFO2(name, entry, exit, ...) \
154 MODULE_INFO2_FLAGS(true, true, name, entry, exit, __VA_ARGS__)
155
156#define MODULE_OPTIONAL_DEPENDS(...) \
157 static const char* __mod_opt_deps[] = {__VA_ARGS__, 0}; \
158 static StaticDriverOptionalDependencies __module_opt_dependencies(__module, __mod_opt_deps)
159
160#else
161
162#define MODULE_NAME(x) const char* g_pModuleName EXPORTED_PUBLIC SECTION(".modinfo") USED = x
163#define MODULE_ENTRY(x) ModuleEntry g_pModuleEntry EXPORTED_PUBLIC SECTION(".modinfo") USED = x
164#define MODULE_EXIT(x) ModuleExit g_pModuleExit EXPORTED_PUBLIC SECTION(".modinfo") USED = x
165#define MODULE_UNLOADABLE(x) bool g_bModuleUnloadable EXPORTED_PUBLIC SECTION(".modinfo") USED = x
166#define MODULE_RUNTIME_UNLOADABLE(x) \
167 bool g_bModuleRuntimeUnloadable EXPORTED_PUBLIC SECTION(".modinfo") USED = x
168#define MODULE_DEPENDS(...) \
169 const char* g_pDepends[] EXPORTED_PUBLIC SECTION(".modinfo") USED = {__VA_ARGS__, 0}
170#define MODULE_DEPENDS2(...) \
171 const char* g_pDepends[] EXPORTED_PUBLIC SECTION(".modinfo") USED = {__VA_ARGS__}
172
173#define MODULE_OPTIONAL_DEPENDS(...) \
174 const char* g_pOptionalDepends[] EXPORTED_PUBLIC SECTION(".modinfo") USED = {__VA_ARGS__, 0}
175
176#define MODULE_INFO2_FLAGS(unloadable, runtimeUnloadable, name, entry, exit, ...) \
177 MODULE_NAME(name); \
178 MODULE_ENTRY(entry); \
179 MODULE_EXIT(exit); \
180 MODULE_UNLOADABLE(unloadable); \
181 MODULE_RUNTIME_UNLOADABLE(runtimeUnloadable); \
182 MODULE_DEPENDS2(__VA_ARGS__);
183
184#define MODULE_INFO2(name, entry, exit, ...) \
185 MODULE_INFO2_FLAGS(true, true, name, entry, exit, __VA_ARGS__)
186
187extern const char* g_pModuleName;
188extern ModuleEntry g_pModuleEntry;
189extern ModuleExit g_pModuleExit;
190extern bool g_bModuleUnloadable;
191extern bool g_bModuleRuntimeUnloadable;
192extern const char* g_pDepends[];
193extern const char* g_pOptionalDepends[];
194
195#endif
196
197#define MODULE_INFO(...) MODULE_INFO2(__VA_ARGS__, 0)
198#define MODULE_INFO_NON_UNLOADABLE(...) MODULE_INFO2_FLAGS(false, false, __VA_ARGS__, 0)
199#define MODULE_INFO_RUNTIME_PINNED(...) MODULE_INFO2_FLAGS(true, false, __VA_ARGS__, 0)
200
201#endif