summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-07-13 20:07:07 +0200
committerRichard Braun <rbraun@sceen.net>2017-07-13 20:07:07 +0200
commitdd78bb04876f66e967773d6dd03ea9534fe43cc2 (patch)
tree4d3080abf0cbcca7c058cba5cad2ed71e5d5e1e5 /kern
parent85292d947faabe8828810946c7a8067ef228d6fe (diff)
Switch to initialization operations
Diffstat (limited to 'kern')
-rw-r--r--kern/arg.c24
-rw-r--r--kern/arg.h14
-rw-r--r--kern/console.c20
-rw-r--r--kern/console.h19
-rw-r--r--kern/cpumap.c9
-rw-r--r--kern/cpumap.h13
-rw-r--r--kern/intr.c24
-rw-r--r--kern/intr.h20
-rw-r--r--kern/kernel.c38
-rw-r--r--kern/kmem.c33
-rw-r--r--kern/kmem.h22
-rw-r--r--kern/llsync.c14
-rw-r--r--kern/llsync.h5
-rw-r--r--kern/log.c36
-rw-r--r--kern/log.h21
-rw-r--r--kern/macros.h10
-rw-r--r--kern/mutex.c11
-rw-r--r--kern/mutex.h9
-rw-r--r--kern/panic.c12
-rw-r--r--kern/panic.h8
-rw-r--r--kern/percpu.c22
-rw-r--r--kern/percpu.h32
-rw-r--r--kern/printf.c10
-rw-r--r--kern/printf.h8
-rw-r--r--kern/rdxtree.c7
-rw-r--r--kern/rdxtree.h6
-rw-r--r--kern/shell.c10
-rw-r--r--kern/shell.h15
-rw-r--r--kern/shutdown.c31
-rw-r--r--kern/shutdown.h18
-rw-r--r--kern/sleepq.c13
-rw-r--r--kern/sleepq.h27
-rw-r--r--kern/spinlock.c10
-rw-r--r--kern/spinlock.h9
-rw-r--r--kern/sref.c21
-rw-r--r--kern/sref.h14
-rw-r--r--kern/syscnt.c30
-rw-r--r--kern/syscnt.h20
-rw-r--r--kern/task.c23
-rw-r--r--kern/task.h13
-rw-r--r--kern/thread.c80
-rw-r--r--kern/thread.h33
-rw-r--r--kern/turnstile.c13
-rw-r--r--kern/turnstile.h28
-rw-r--r--kern/work.c14
-rw-r--r--kern/work.h14
-rw-r--r--kern/xcall.c10
-rw-r--r--kern/xcall.h5
48 files changed, 630 insertions, 268 deletions
diff --git a/kern/arg.c b/kern/arg.c
index 62ace8be..7bb616a4 100644
--- a/kern/arg.c
+++ b/kern/arg.c
@@ -35,22 +35,17 @@ static char arg_cmdline[ARG_CMDLINE_MAX_SIZE] __initdata;
static const char *arg_cmdline_end __initdata;
void __init
-arg_setup(const char *cmdline)
+arg_set_cmdline(const char *cmdline)
{
- size_t i, length;
-
- if (cmdline == NULL) {
- arg_cmdline[0] = '\0';
- return;
- }
-
- length = strlen(cmdline);
+ strlcpy(arg_cmdline, cmdline, sizeof(arg_cmdline));
+}
- if ((length + 1) > ARRAY_SIZE(arg_cmdline)) {
- panic("arg: command line too long");
- }
+static int __init
+arg_setup(void)
+{
+ size_t i, length;
- memcpy(arg_cmdline, cmdline, length + 1);
+ length = strlen(arg_cmdline);
for (i = 0; i < length; i++) {
if (arg_cmdline[i] == ' ') {
@@ -59,8 +54,11 @@ arg_setup(const char *cmdline)
}
arg_cmdline_end = arg_cmdline + length;
+ return 0;
}
+INIT_OP_DEFINE(arg_setup);
+
void __init
arg_log_info(void)
{
diff --git a/kern/arg.h b/kern/arg.h
index 3a8d20ba..c7b70a37 100644
--- a/kern/arg.h
+++ b/kern/arg.h
@@ -27,12 +27,16 @@
#include <stdbool.h>
+#include <kern/init.h>
+
#define ARG_CMDLINE_MAX_SIZE 256
/*
- * Initialize the arg module.
+ * Set the command line string.
+ *
+ * This function must be called before calling the kernel main entry point.
*/
-void arg_setup(const char *cmdline);
+void arg_set_cmdline(const char *cmdline);
/*
* Log command line information.
@@ -54,4 +58,10 @@ bool arg_present(const char *name);
*/
const char * arg_value(const char *name);
+/*
+ * This init operation provides :
+ * - command line arguments can be retrieved
+ */
+INIT_OP_DECLARE(arg_setup);
+
#endif /* _KERN_ARG_H */
diff --git a/kern/console.c b/kern/console.c
index e026ffd5..1f9a8a9c 100644
--- a/kern/console.c
+++ b/kern/console.c
@@ -29,6 +29,7 @@
#include <kern/mutex.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
+#include <machine/boot.h>
#include <machine/cpu.h>
/*
@@ -129,13 +130,28 @@ out:
return c;
}
-void __init
-console_setup(void)
+static int __init
+console_bootstrap(void)
{
list_init(&console_devs);
console_name = arg_value("console");
+ return 0;
+}
+
+INIT_OP_DEFINE(console_bootstrap,
+ INIT_OP_DEP(arg_setup, true),
+ INIT_OP_DEP(log_setup, true));
+
+static int __init
+console_setup(void)
+{
+ return 0;
}
+INIT_OP_DEFINE(console_setup,
+ INIT_OP_DEP(boot_setup_console, true),
+ INIT_OP_DEP(thread_setup, true));
+
void __init
console_register(struct console *console)
{
diff --git a/kern/console.h b/kern/console.h
index a5aa478d..15789974 100644
--- a/kern/console.h
+++ b/kern/console.h
@@ -22,6 +22,7 @@
#define _KERN_CONSOLE_H
#include <kern/cbuf.h>
+#include <kern/init.h>
#include <kern/list.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
@@ -62,11 +63,6 @@ void console_init(struct console *console, const char *name,
const struct console_ops *ops);
/*
- * Initialize the console module.
- */
-void console_setup(void);
-
-/*
* Register a console device.
*
* The given console must be initialized before calling this function.
@@ -95,4 +91,17 @@ void console_intr(struct console *console, const char *s);
void console_putchar(char c);
char console_getchar(void);
+/*
+ * This init operation provides :
+ * - registration of consoles
+ */
+INIT_OP_DECLARE(console_bootstrap);
+
+/*
+ * This init operation provides :
+ * - all consoles have been registered
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(console_setup);
+
#endif /* _KERN_CONSOLE_H */
diff --git a/kern/cpumap.c b/kern/cpumap.c
index e4ae864e..d166b237 100644
--- a/kern/cpumap.c
+++ b/kern/cpumap.c
@@ -20,6 +20,7 @@
#include <kern/bitmap.h>
#include <kern/cpumap.h>
#include <kern/error.h>
+#include <kern/init.h>
#include <kern/kmem.h>
#include <kern/macros.h>
#include <machine/cpu.h>
@@ -28,7 +29,7 @@ static struct cpumap cpumap_active_cpus __read_mostly = { { 1 } };
static struct kmem_cache cpumap_cache;
-void
+static int __init
cpumap_setup(void)
{
unsigned int i, nr_cpus;
@@ -40,8 +41,14 @@ cpumap_setup(void)
for (i = 0; i < nr_cpus; i++) {
cpumap_set(&cpumap_active_cpus, i);
}
+
+ return 0;
}
+INIT_OP_DEFINE(cpumap_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(cpu_mp_probe, true));
+
const struct cpumap *
cpumap_all(void)
{
diff --git a/kern/cpumap.h b/kern/cpumap.h
index 1843a99a..fd07afc1 100644
--- a/kern/cpumap.h
+++ b/kern/cpumap.h
@@ -27,6 +27,7 @@
#define _KERN_CPUMAP_H
#include <kern/bitmap.h>
+#include <kern/init.h>
struct cpumap {
BITMAP_DECLARE(cpus, X15_MAX_CPUS);
@@ -135,11 +136,6 @@ cpumap_find_first_zero(const struct cpumap *cpumap)
bitmap_for_each_zero((cpumap)->cpus, X15_MAX_CPUS, index)
/*
- * Initialize the cpumap module.
- */
-void cpumap_setup(void);
-
-/*
* Return a cpumap representing all active processors.
*
* Until the cpumap module is initialized, the cpumap returned by this
@@ -167,4 +163,11 @@ void cpumap_destroy(struct cpumap *cpumap);
*/
int cpumap_check(const struct cpumap *cpumap);
+/*
+ * This init operation provides :
+ * - cpumap creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(cpumap_setup);
+
#endif /* _KERN_CPUMAP_H */
diff --git a/kern/intr.c b/kern/intr.c
index 769f4d93..8579b744 100644
--- a/kern/intr.c
+++ b/kern/intr.c
@@ -36,6 +36,7 @@
#include <kern/panic.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
+#include <machine/boot.h>
#include <machine/cpu.h>
#include <machine/trap.h>
@@ -315,8 +316,8 @@ intr_get_entry(unsigned int intr)
return &intr_table[intr];
}
-void __init
-intr_setup(void)
+static int __init
+intr_bootstrap(void)
{
unsigned int i;
@@ -328,8 +329,27 @@ intr_setup(void)
for (i = 0; i < ARRAY_SIZE(intr_table); i++) {
intr_entry_init(intr_get_entry(i));
}
+
+ return 0;
}
+INIT_OP_DEFINE(intr_bootstrap,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(spinlock_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true));
+
+static int __init
+intr_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(intr_setup,
+ INIT_OP_DEP(boot_setup_intr, true),
+ INIT_OP_DEP(intr_bootstrap, true));
+
static void __init
intr_check_range(unsigned int first_intr, unsigned int last_intr)
{
diff --git a/kern/intr.h b/kern/intr.h
index 1cdab5ef..ac3f8cf2 100644
--- a/kern/intr.h
+++ b/kern/intr.h
@@ -21,6 +21,8 @@
#ifndef _KERN_INTR_H
#define _KERN_INTR_H
+#include <kern/init.h>
+
/*
* Type for interrupt handler functions.
*
@@ -42,11 +44,6 @@ struct intr_ops {
};
/*
- * Initialize the intr module.
- */
-void intr_setup(void);
-
-/*
* Register an interrupt controller.
*
* This function isn't thread-safe and can only be called during system
@@ -66,4 +63,17 @@ void intr_unregister(unsigned int intr, intr_handler_fn_t fn);
*/
void intr_handle(unsigned int intr);
+/*
+ * This init operation provides :
+ * - registration of interrupt controllers and handlers
+ */
+INIT_OP_DECLARE(intr_bootstrap);
+
+/*
+ * This init operation provides :
+ * - all interrupt controllers have been registered
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(intr_setup);
+
#endif /* _KERN_INTR_H */
diff --git a/kern/kernel.c b/kern/kernel.c
index 6c562f4d..434297d3 100644
--- a/kern/kernel.c
+++ b/kern/kernel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 Richard Braun.
+ * Copyright (c) 2011-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
@@ -15,53 +15,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <kern/cpumap.h>
#include <kern/init.h>
#include <kern/kernel.h>
-#include <kern/llsync.h>
-#include <kern/log.h>
-#include <kern/percpu.h>
-#include <kern/shell.h>
-#include <kern/shutdown.h>
-#include <kern/sleepq.h>
-#include <kern/sref.h>
-#include <kern/syscnt.h>
-#include <kern/task.h>
#include <kern/thread.h>
-#include <kern/turnstile.h>
-#include <kern/work.h>
-#include <kern/xcall.h>
#include <machine/cpu.h>
#include <vm/vm_page.h>
-#ifdef X15_RUN_TEST_MODULE
-#include <test/test.h>
-#endif /* X15_RUN_TEST_MODULE */
-
void __init
kernel_main(void)
{
assert(!cpu_intr_enabled());
- percpu_cleanup();
- shell_setup();
- syscnt_register_shell_cmds();
- cpumap_setup();
- xcall_setup();
- task_setup();
- sleepq_setup();
- turnstile_setup();
- thread_setup();
- work_setup();
- llsync_setup();
- sref_setup();
+ init_setup();
vm_page_log_info();
- shutdown_register_shell_cmds();
- log_start();
-
-#ifdef X15_RUN_TEST_MODULE
- test_setup();
-#endif /* X15_RUN_TEST_MODULE */
/*
* Enabling application processors is done late in the boot process for
diff --git a/kern/kmem.c b/kern/kmem.c
index 572df4fe..d98be0d6 100644
--- a/kern/kmem.c
+++ b/kern/kmem.c
@@ -1171,10 +1171,23 @@ static struct shell_cmd kmem_shell_cmds[] = {
"display information about kernel memory and caches"),
};
+static int __init
+kmem_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(kmem_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(kmem_setup_shell,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(thread_setup, true));
+
#endif /* X15_SHELL */
-void __init
-kmem_setup(void)
+static int __init
+kmem_bootstrap(void)
{
struct kmem_cpu_pool_type *cpu_pool_type;
char name[KMEM_NAME_SIZE];
@@ -1209,9 +1222,23 @@ kmem_setup(void)
size <<= 1;
}
- SHELL_REGISTER_CMDS(kmem_shell_cmds);
+ return 0;
}
+INIT_OP_DEFINE(kmem_bootstrap,
+ INIT_OP_DEP(thread_bootstrap, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
+static int __init
+kmem_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(kmem_setup,
+ INIT_OP_DEP(kmem_bootstrap, true),
+ INIT_OP_DEP(vm_kmem_setup, true));
+
static inline size_t
kmem_get_index(unsigned long size)
{
diff --git a/kern/kmem.h b/kern/kmem.h
index 8f6c773c..3296ddb4 100644
--- a/kern/kmem.h
+++ b/kern/kmem.h
@@ -23,6 +23,8 @@
#include <stddef.h>
+#include <kern/init.h>
+
/*
* Object cache.
*/
@@ -77,14 +79,6 @@ void kmem_cache_free(struct kmem_cache *cache, void *obj);
void kmem_cache_info(struct kmem_cache *cache);
/*
- * Set up the kernel memory allocator module.
- *
- * This function should only be called by the VM system. Once it returns,
- * caches can be initialized.
- */
-void kmem_setup(void);
-
-/*
* Allocate size bytes of uninitialized memory.
*/
void * kmem_alloc(size_t size);
@@ -106,4 +100,16 @@ void kmem_free(void *ptr, size_t size);
*/
void kmem_info(void);
+/*
+ * This init operation provides :
+ * - allocation from caches backed by the page allocator
+ */
+INIT_OP_DECLARE(kmem_bootstrap);
+
+/*
+ * This init operation provides :
+ * - allocation from all caches
+ */
+INIT_OP_DECLARE(kmem_setup);
+
#endif /* _KERN_KMEM_H */
diff --git a/kern/llsync.c b/kern/llsync.c
index 8ba87b67..c432fc68 100644
--- a/kern/llsync.c
+++ b/kern/llsync.c
@@ -49,6 +49,7 @@
#include <kern/spinlock.h>
#include <kern/syscnt.h>
#include <kern/work.h>
+#include <kern/thread.h>
#include <machine/cpu.h>
/*
@@ -81,7 +82,7 @@ llsync_ready(void)
return llsync_is_ready;
}
-void __init
+static int __init
llsync_setup(void)
{
struct llsync_cpu_data *cpu_data;
@@ -102,8 +103,19 @@ llsync_setup(void)
cpu_data = percpu_ptr(llsync_cpu_data, i);
work_queue_init(&cpu_data->queue0);
}
+
+ return 0;
}
+INIT_OP_DEFINE(llsync_setup,
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(spinlock_setup, true),
+ INIT_OP_DEP(syscnt_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true),
+ INIT_OP_DEP(work_setup, true));
+
static void
llsync_process_global_checkpoint(void)
{
diff --git a/kern/llsync.h b/kern/llsync.h
index 6736d6f9..3852b0b9 100644
--- a/kern/llsync.h
+++ b/kern/llsync.h
@@ -123,11 +123,6 @@ llsync_read_exit(void)
bool llsync_ready(void);
/*
- * Initialize the llsync module.
- */
-void llsync_setup(void);
-
-/*
* Manage registration of the current processor.
*
* The caller must not be allowed to migrate when calling these functions.
diff --git a/kern/log.c b/kern/log.c
index 96be1528..0ddf6790 100644
--- a/kern/log.c
+++ b/kern/log.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <string.h>
+#include <kern/arg.h>
#include <kern/cbuf.h>
#include <kern/init.h>
#include <kern/log.h>
@@ -32,6 +33,8 @@
#include <kern/shell.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
+#include <machine/boot.h>
+#include <machine/cpu.h>
#define LOG_BUFFER_SIZE 16384
@@ -396,18 +399,40 @@ static struct shell_cmd log_shell_cmds[] = {
" 7: debug"),
};
+static int __init
+log_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(log_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(log_setup_shell,
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(shell_setup, true));
+
#endif /* X15_SHELL */
-void __init
+static int __init
log_setup(void)
{
cbuf_init(&log_cbuf, log_buffer, sizeof(log_buffer));
log_index = cbuf_start(&log_cbuf);
spinlock_init(&log_lock);
log_print_level = LOG_INFO;
+
+ boot_log_info();
+ arg_log_info();
+ cpu_log_info(cpu_current());
+
+ return 0;
}
-void __init
+INIT_OP_DEFINE(log_setup,
+ INIT_OP_DEP(arg_setup, true),
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(spinlock_setup, true));
+
+static int __init
log_start(void)
{
struct thread_attr attr;
@@ -421,9 +446,14 @@ log_start(void)
panic("log: unable to create thread");
}
- SHELL_REGISTER_CMDS(log_shell_cmds);
+ return 0;
}
+INIT_OP_DEFINE(log_start,
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(thread_setup, true));
+
static void
log_write(const void *s, size_t size)
{
diff --git a/kern/log.h b/kern/log.h
index 003e99b2..581a7840 100644
--- a/kern/log.h
+++ b/kern/log.h
@@ -23,6 +23,8 @@
#include <stdarg.h>
+
+#include <kern/init.h>
enum {
LOG_EMERG,
LOG_ALERT,
@@ -36,16 +38,6 @@ enum {
};
/*
- * Initialize the log module.
- */
-void log_setup(void);
-
-/*
- * Start the log thread.
- */
-void log_start(void);
-
-/*
* Generate a message and send it to the log thread.
*
* The arguments and return value are similar to printf(), with
@@ -92,4 +84,13 @@ int log_vinfo(const char *format, va_list ap)
int log_vdebug(const char *format, va_list ap)
__attribute__((format(printf, 1, 0)));
+/*
+ * This init operation provides :
+ * - message logging
+ *
+ * The log thread isn't yet started and messages are merely stored in an
+ * internal buffer.
+ */
+INIT_OP_DECLARE(log_setup);
+
#endif /* _KERN_LOG_H */
diff --git a/kern/macros.h b/kern/macros.h
index 6259dcee..6b203e52 100644
--- a/kern/macros.h
+++ b/kern/macros.h
@@ -43,6 +43,16 @@
#define DECL_CONST(x, s) x
#else /* __ASSEMBLER__ */
#define __DECL_CONST(x, s) x##s
+void cga_putc(char c);
+
+static inline void
+moo_print(const char *s)
+{
+ while (*s != '\0') {
+ cga_putc(*s);
+ s++;
+ }
+}
#define DECL_CONST(x, s) __DECL_CONST(x, s)
#endif /* __ASSEMBLER__ */
diff --git a/kern/mutex.c b/kern/mutex.c
index 7899bef9..87e3d64e 100644
--- a/kern/mutex.c
+++ b/kern/mutex.c
@@ -17,9 +17,9 @@
#ifndef X15_MUTEX_PI
-#include <stdbool.h>
#include <stddef.h>
+#include <kern/init.h>
#include <kern/mutex.h>
#include <kern/mutex_i.h>
#include <kern/sleepq.h>
@@ -69,3 +69,12 @@ mutex_unlock_slow(struct mutex *mutex)
}
#endif /* X15_MUTEX_PI */
+
+static int __init
+mutex_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(mutex_setup,
+ INIT_OP_DEP(thread_setup_booter, true));
diff --git a/kern/mutex.h b/kern/mutex.h
index d09a7bbe..103af02a 100644
--- a/kern/mutex.h
+++ b/kern/mutex.h
@@ -25,6 +25,7 @@
#ifndef _KERN_MUTEX_H
#define _KERN_MUTEX_H
+#include <kern/init.h>
#include <kern/mutex_types.h>
#ifdef X15_MUTEX_PI
@@ -158,4 +159,12 @@ mutex_unlock(struct mutex *mutex)
#endif /* X15_MUTEX_PI */
+/*
+ * This init operation provides :
+ * - uncontended mutex locking
+ *
+ * Contended locking may only occur after starting the scheduler.
+ */
+INIT_OP_DECLARE(mutex_setup);
+
#endif /* _KERN_MUTEX_H */
diff --git a/kern/panic.c b/kern/panic.c
index 9e7d1d53..c610e3fa 100644
--- a/kern/panic.c
+++ b/kern/panic.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <kern/atomic.h>
+#include <kern/init.h>
#include <kern/panic.h>
#include <machine/cpu.h>
#include <machine/strace.h>
@@ -54,3 +55,14 @@ panic(const char *format, ...)
* Never reached.
*/
}
+
+static int __init
+panic_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(panic_setup,
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(strace_setup, true));
diff --git a/kern/panic.h b/kern/panic.h
index e0980575..e6cbe8ba 100644
--- a/kern/panic.h
+++ b/kern/panic.h
@@ -20,10 +20,18 @@
#include <stdnoreturn.h>
+#include <kern/init.h>
+
/*
* Print the given message and halt the system immediately.
*/
noreturn void panic(const char *format, ...)
__attribute__((format(printf, 1, 2)));
+/*
+ * This init operation provides :
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(panic_setup);
+
#endif /* _KERN_PANIC_H */
diff --git a/kern/percpu.c b/kern/percpu.c
index c21376f1..7621bb29 100644
--- a/kern/percpu.c
+++ b/kern/percpu.c
@@ -36,13 +36,16 @@ static void *percpu_area_content __initdata;
static size_t percpu_area_size __initdata;
static int percpu_skip_warning __initdata;
-void __init
+static int __init
percpu_bootstrap(void)
{
percpu_areas[0] = &_percpu;
+ return 0;
}
-void __init
+INIT_OP_DEFINE(percpu_bootstrap);
+
+static int __init
percpu_setup(void)
{
struct vm_page *page;
@@ -54,7 +57,7 @@ percpu_setup(void)
assert(vm_page_aligned(percpu_area_size));
if (percpu_area_size == 0) {
- return;
+ return 0;
}
order = vm_page_order(percpu_area_size);
@@ -66,8 +69,13 @@ percpu_setup(void)
percpu_area_content = vm_page_direct_ptr(page);
memcpy(percpu_area_content, &_percpu, percpu_area_size);
+ return 0;
}
+INIT_OP_DEFINE(percpu_setup,
+ INIT_OP_DEP(percpu_bootstrap, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
int __init
percpu_add(unsigned int cpu)
{
@@ -108,7 +116,7 @@ out:
return 0;
}
-void
+static int __init
percpu_cleanup(void)
{
struct vm_page *page;
@@ -117,4 +125,10 @@ percpu_cleanup(void)
va = (uintptr_t)percpu_area_content;
page = vm_page_lookup(vm_page_direct_pa(va));
vm_page_free(page, vm_page_order(percpu_area_size));
+ return 0;
}
+
+INIT_OP_DEFINE(percpu_cleanup,
+ INIT_OP_DEP(cpu_mp_probe, true),
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(vm_page_setup, true));
diff --git a/kern/percpu.h b/kern/percpu.h
index 18eb8aac..879767ff 100644
--- a/kern/percpu.h
+++ b/kern/percpu.h
@@ -57,6 +57,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <kern/init.h>
#include <kern/macros.h>
#define PERCPU_SECTION .percpu
@@ -95,25 +96,6 @@ percpu_area(unsigned int cpu)
}
/*
- * Early initialization of the percpu module.
- *
- * This function registers the percpu section as the percpu area of the
- * BSP. If a percpu variable is modified before calling percpu_setup(),
- * the modification will be part of the percpu section and propagated to
- * new percpu areas.
- */
-void percpu_bootstrap(void);
-
-/*
- * Complete initialization of the percpu module.
- *
- * The BSP keeps using the percpu section, but its content is copied to a
- * dedicated block of memory used as a template for subsequently added
- * processors.
- */
-void percpu_setup(void);
-
-/*
* Register a processor.
*
* This function creates a percpu area from kernel virtual memory for the
@@ -123,8 +105,16 @@ void percpu_setup(void);
int percpu_add(unsigned int cpu);
/*
- * Release init data allocated for setup.
+ * This init operation provides :
+ * - percpu section is registered as the BSP percpu area
+ */
+INIT_OP_DECLARE(percpu_bootstrap);
+
+/*
+ * This init operation provides :
+ * - percpu section is copied to a kernel buffer subsequently used as
+ * the template for future percpu areas
*/
-void percpu_cleanup(void);
+INIT_OP_DECLARE(percpu_setup);
#endif /* _KERN_PERCPU_H */
diff --git a/kern/printf.c b/kern/printf.c
index 64324a04..68cf4ba9 100644
--- a/kern/printf.c
+++ b/kern/printf.c
@@ -17,7 +17,9 @@
#include <kern/console.h>
#include <kern/fmt.h>
+#include <kern/init.h>
#include <kern/spinlock.h>
+#include <machine/boot.h>
#include <machine/cpu.h>
/*
@@ -61,8 +63,14 @@ vprintf(const char *format, va_list ap)
return length;
}
-void
+static int __init
printf_setup(void)
{
spinlock_init(&printf_lock);
+ return 0;
}
+
+INIT_OP_DEFINE(printf_setup,
+ INIT_OP_DEP(boot_bootstrap_console, true),
+ INIT_OP_DEP(console_bootstrap, true),
+ INIT_OP_DEP(spinlock_setup, true));
diff --git a/kern/printf.h b/kern/printf.h
index 0aed7200..8185c735 100644
--- a/kern/printf.h
+++ b/kern/printf.h
@@ -33,12 +33,18 @@
#include <stdarg.h>
+#include <kern/init.h>
+
int printf(const char *format, ...)
__attribute__((format(printf, 1, 2)));
int vprintf(const char *format, va_list ap)
__attribute__((format(printf, 1, 0)));
-void printf_setup(void);
+/*
+ * This init operation provides :
+ * - printf is usable
+ */
+INIT_OP_DECLARE(printf_setup);
#endif /* _KERN_PRINTF_H */
diff --git a/kern/rdxtree.c b/kern/rdxtree.c
index 77f6a68a..77005b64 100644
--- a/kern/rdxtree.c
+++ b/kern/rdxtree.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <kern/error.h>
+#include <kern/init.h>
#include <kern/kmem.h>
#include <kern/llsync.h>
#include <kern/macros.h>
@@ -895,10 +896,14 @@ rdxtree_remove_all(struct rdxtree *tree)
}
}
-void
+static int __init
rdxtree_setup(void)
{
kmem_cache_init(&rdxtree_node_cache, "rdxtree_node",
sizeof(struct rdxtree_node), 0,
rdxtree_node_ctor, KMEM_CACHE_PAGE_ONLY);
+ return 0;
}
+
+INIT_OP_DEFINE(rdxtree_setup,
+ INIT_OP_DEP(kmem_bootstrap, true));
diff --git a/kern/rdxtree.h b/kern/rdxtree.h
index a30512cf..6ae1e6e7 100644
--- a/kern/rdxtree.h
+++ b/kern/rdxtree.h
@@ -29,6 +29,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <kern/init.h>
#include <kern/llsync.h>
typedef uint64_t rdxtree_key_t;
@@ -200,8 +201,9 @@ rdxtree_iter_key(const struct rdxtree_iter *iter)
void rdxtree_remove_all(struct rdxtree *tree);
/*
- * Initialize the rdxtree module.
+ * This init operation provides :
+ * - module fully initialized
*/
-void rdxtree_setup(void);
+INIT_OP_DECLARE(rdxtree_setup);
#endif /* _KERN_RDXTREE_H */
diff --git a/kern/shell.c b/kern/shell.c
index 6be17cd1..a27c53f3 100644
--- a/kern/shell.c
+++ b/kern/shell.c
@@ -18,7 +18,6 @@
#include <stdio.h>
#include <string.h>
-#include <kern/console.h>
#include <kern/error.h>
#include <kern/hash.h>
#include <kern/init.h>
@@ -1183,7 +1182,7 @@ shell_run(void *arg)
}
}
-void __init
+static int __init
shell_setup(void)
{
unsigned long i;
@@ -1195,8 +1194,15 @@ shell_setup(void)
error = shell_cmd_register(&shell_default_cmds[i]);
error_check(error, "shell_cmd_register");
}
+
+ return 0;
}
+INIT_OP_DEFINE(shell_setup,
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(printf_setup, true));
+
void __init
shell_start(void)
{
diff --git a/kern/shell.h b/kern/shell.h
index 81be314b..cf56cebf 100644
--- a/kern/shell.h
+++ b/kern/shell.h
@@ -21,6 +21,7 @@
#ifndef _KERN_SHELL_H
#define _KERN_SHELL_H
+#include <kern/init.h>
#include <kern/error.h>
#include <kern/macros.h>
@@ -65,13 +66,6 @@ void shell_cmd_init(struct shell_cmd *cmd, const char *name,
const char *short_desc, const char *long_desc);
/*
- * Initialize the shell module.
- *
- * On return, shell commands can be registered.
- */
-void shell_setup(void);
-
-/*
* Start the shell thread.
*/
void shell_start(void);
@@ -93,4 +87,11 @@ int shell_cmd_register(struct shell_cmd *cmd);
#define shell_start()
#endif /* X15_SHELL */
+/*
+ * This init operation provides :
+ * - commands can be registered
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(shell_setup);
+
#endif /* _KERN_SHELL_H */
diff --git a/kern/shutdown.c b/kern/shutdown.c
index 11a51832..1c950415 100644
--- a/kern/shutdown.c
+++ b/kern/shutdown.c
@@ -21,6 +21,7 @@
#include <kern/plist.h>
#include <kern/shell.h>
#include <kern/shutdown.h>
+#include <machine/boot.h>
#include <machine/cpu.h>
static struct plist shutdown_ops_list;
@@ -54,20 +55,40 @@ static struct shell_cmd shutdown_shell_cmds[] = {
"reboot the system"),
};
+static int __init
+shutdown_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(shutdown_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(shutdown_setup_shell,
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(shutdown_setup, true));
+
#endif /* X15_SHELL */
-void __init
-shutdown_setup(void)
+static int __init
+shutdown_bootstrap(void)
{
plist_init(&shutdown_ops_list);
+ return 0;
}
-void __init
-shutdown_register_shell_cmds(void)
+INIT_OP_DEFINE(shutdown_bootstrap);
+
+static int __init
+shutdown_setup(void)
{
- SHELL_REGISTER_CMDS(shutdown_shell_cmds);
+ return 0;
}
+INIT_OP_DEFINE(shutdown_setup,
+ INIT_OP_DEP(boot_setup_shutdown, true),
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shutdown_bootstrap, true));
+
void __init
shutdown_register(struct shutdown_ops *ops, unsigned int priority)
{
diff --git a/kern/shutdown.h b/kern/shutdown.h
index f7bc1879..f61079b3 100644
--- a/kern/shutdown.h
+++ b/kern/shutdown.h
@@ -20,6 +20,7 @@
#include <stdnoreturn.h>
+#include <kern/init.h>
#include <kern/plist.h>
struct shutdown_ops {
@@ -27,13 +28,22 @@ struct shutdown_ops {
void (*reset)(void);
};
-void shutdown_setup(void);
-
-void shutdown_register_shell_cmds(void);
-
void shutdown_register(struct shutdown_ops *ops, unsigned int priority);
noreturn void shutdown_halt(void);
noreturn void shutdown_reboot(void);
+/*
+ * This init operation provides :
+ * - registration of shutdown operations
+ */
+INIT_OP_DECLARE(shutdown_bootstrap);
+
+/*
+ * This init operation provides :
+ * - all shutdown operations have been registered
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(shutdown_setup);
+
#endif /* _KERN_SHUTDOWN_H */
diff --git a/kern/sleepq.c b/kern/sleepq.c
index d8bbbddf..cc85705d 100644
--- a/kern/sleepq.c
+++ b/kern/sleepq.c
@@ -193,7 +193,7 @@ sleepq_ctor(void *ptr)
sleepq->next_free = NULL;
}
-void __init
+static int __init
sleepq_bootstrap(void)
{
unsigned int i;
@@ -205,15 +205,24 @@ sleepq_bootstrap(void)
for (i = 0; i < ARRAY_SIZE(sleepq_cond_htable); i++) {
sleepq_bucket_init(&sleepq_cond_htable[i]);
}
+
+ return 0;
}
-void __init
+INIT_OP_DEFINE(sleepq_bootstrap);
+
+static int __init
sleepq_setup(void)
{
kmem_cache_init(&sleepq_cache, "sleepq", sizeof(struct sleepq),
CPU_L1_SIZE, sleepq_ctor, 0);
+ return 0;
}
+INIT_OP_DEFINE(sleepq_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(sleepq_bootstrap, true));
+
struct sleepq *
sleepq_create(void)
{
diff --git a/kern/sleepq.h b/kern/sleepq.h
index e1f7863b..0660226c 100644
--- a/kern/sleepq.h
+++ b/kern/sleepq.h
@@ -41,20 +41,6 @@
struct sleepq;
/*
- * Early initialization of the sleepq module.
- *
- * This module is initialized by architecture-specific code. It should
- * be one of the first modules to be initialized since it's used by
- * synchronization objects that may be accessed very early.
- */
-void sleepq_bootstrap(void);
-
-/*
- * Initialize the sleepq module.
- */
-void sleepq_setup(void);
-
-/*
* Create/destroy a sleep queue.
*/
struct sleepq * sleepq_create(void);
@@ -136,4 +122,17 @@ void sleepq_wait(struct sleepq *sleepq, const char *wchan);
*/
void sleepq_signal(struct sleepq *sleepq);
+/*
+ * This init operation provides :
+ * - ? TODO Review
+ */
+INIT_OP_DECLARE(sleepq_bootstrap);
+
+/*
+ * This init operation provides :
+ * - sleepq creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(sleepq_setup);
+
#endif /* _KERN_SLEEPQ_H */
diff --git a/kern/spinlock.c b/kern/spinlock.c
index 6b23b36b..fcb7c7b6 100644
--- a/kern/spinlock.c
+++ b/kern/spinlock.c
@@ -69,6 +69,7 @@
#include <kern/atomic.h>
#include <kern/error.h>
+#include <kern/init.h>
#include <kern/macros.h>
#include <kern/percpu.h>
#include <kern/spinlock.h>
@@ -329,3 +330,12 @@ spinlock_unlock_slow(struct spinlock *lock)
next_qnode = spinlock_get_remote_qnode(next_qid);
atomic_store_release(&next_qnode->locked, false);
}
+
+static int __init
+spinlock_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(spinlock_setup,
+ INIT_OP_DEP(thread_setup_booter, true));
diff --git a/kern/spinlock.h b/kern/spinlock.h
index 4dc4c83e..d4105da0 100644
--- a/kern/spinlock.h
+++ b/kern/spinlock.h
@@ -26,6 +26,7 @@
#ifndef _KERN_SPINLOCK_H
#define _KERN_SPINLOCK_H
+#include <kern/init.h>
#include <kern/macros.h>
#include <kern/spinlock_i.h>
#include <kern/spinlock_types.h>
@@ -162,4 +163,12 @@ spinlock_unlock_intr_restore(struct spinlock *lock, unsigned long flags)
thread_preempt_enable();
}
+/*
+ * This init operation provides :
+ * - uncontended spinlock locking
+ *
+ * Contended locking may only occur after starting APs.
+ */
+INIT_OP_DECLARE(spinlock_setup);
+
#endif /* _KERN_SPINLOCK_H */
diff --git a/kern/sref.c b/kern/sref.c
index 7167efff..9c49a425 100644
--- a/kern/sref.c
+++ b/kern/sref.c
@@ -816,7 +816,7 @@ sref_manage(void *arg)
/* Never reached */
}
-void __init
+static int __init
sref_bootstrap(void)
{
spinlock_init(&sref_data.lock);
@@ -828,8 +828,13 @@ sref_bootstrap(void)
syscnt_register(&sref_data.sc_true_zeroes, "sref_true_zeroes");
sref_cache_init(sref_cache_get(), 0);
+
+ return 0;
}
+INIT_OP_DEFINE(sref_bootstrap,
+ INIT_OP_DEP(syscnt_setup, true));
+
static void __init
sref_setup_manager(struct sref_cache *cache, unsigned int cpu)
{
@@ -861,7 +866,7 @@ sref_setup_manager(struct sref_cache *cache, unsigned int cpu)
cache->manager = manager;
}
-void __init
+static int __init
sref_setup(void)
{
unsigned int i;
@@ -873,8 +878,20 @@ sref_setup(void)
for (i = 0; i < cpu_count(); i++) {
sref_setup_manager(percpu_ptr(sref_cache, i), i);
}
+
+ return 0;
}
+INIT_OP_DEFINE(sref_setup,
+ INIT_OP_DEP(cpu_mp_probe, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(sref_bootstrap, true),
+ INIT_OP_DEP(syscnt_setup, true),
+ INIT_OP_DEP(thread_setup, true));
+
void
sref_register(void)
{
diff --git a/kern/sref.h b/kern/sref.h
index ac16b13d..5299b9d2 100644
--- a/kern/sref.h
+++ b/kern/sref.h
@@ -49,20 +49,6 @@ typedef void (*sref_noref_fn_t)(struct sref_counter *);
#include <kern/sref_i.h>
/*
- * Early initialization of the sref module.
- *
- * This function depends on the availability of percpu variables.
- */
-void sref_bootstrap(void);
-
-/*
- * Initialize the sref module.
- *
- * This function mostly takes care of setting up periodic maintenance.
- */
-void sref_setup(void);
-
-/*
* Manage registration of the current processor.
*
* Registering tells the sref module that the current processor reports
diff --git a/kern/syscnt.c b/kern/syscnt.c
index d5fd28ab..7cceabac 100644
--- a/kern/syscnt.c
+++ b/kern/syscnt.c
@@ -32,13 +32,6 @@
static struct list syscnt_list;
static struct mutex syscnt_lock;
-void __init
-syscnt_setup(void)
-{
- list_init(&syscnt_list);
- mutex_init(&syscnt_lock);
-}
-
#ifdef X15_SHELL
static void
@@ -50,21 +43,36 @@ syscnt_shell_info(int argc, char **argv)
syscnt_info(prefix);
}
-
static struct shell_cmd syscnt_shell_cmds[] = {
SHELL_CMD_INITIALIZER("syscnt_info", syscnt_shell_info,
"syscnt_info [<prefix>]",
"display information about system counters"),
};
+static int __init
+syscnt_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(syscnt_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(syscnt_setup_shell,
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(syscnt_setup, true));
+
#endif /* X15_SHELL */
-void __init
-syscnt_register_shell_cmds(void)
+static int __init
+syscnt_setup(void)
{
- SHELL_REGISTER_CMDS(syscnt_shell_cmds);
+ list_init(&syscnt_list);
+ mutex_init(&syscnt_lock);
+ return 0;
}
+INIT_OP_DEFINE(syscnt_setup,
+ INIT_OP_DEP(mutex_setup, true));
+
void __init
syscnt_register(struct syscnt *syscnt, const char *name)
{
diff --git a/kern/syscnt.h b/kern/syscnt.h
index 35a291d9..816aa4b9 100644
--- a/kern/syscnt.h
+++ b/kern/syscnt.h
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <kern/atomic.h>
+#include <kern/init.h>
#include <kern/macros.h>
#include <kern/spinlock.h>
@@ -43,25 +44,12 @@
struct syscnt;
/*
- * Initialize the syscnt module.
- *
- * This module is initialized by architecture-specific code. It is normally
- * safe to call this function very early at boot time.
- */
-void syscnt_setup(void);
-
-/*
* Initialize and register the given counter.
*
* The counter is set to 0.
*/
void syscnt_register(struct syscnt *syscnt, const char *name);
-/*
- * Register shell commands.
- */
-void syscnt_register_shell_cmds(void);
-
#ifdef ATOMIC_HAVE_64B_OPS
static inline void
@@ -123,4 +111,10 @@ syscnt_dec(struct syscnt *syscnt)
*/
void syscnt_info(const char *prefix);
+/*
+ * This init operation provides :
+ * - registration of system counters
+ */
+INIT_OP_DECLARE(syscnt_setup);
+
#endif /* _KERN_SYSCNT_H */
diff --git a/kern/task.c b/kern/task.c
index 9764cfe0..ab82ad83 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -99,9 +99,22 @@ static struct shell_cmd task_shell_cmds[] = {
"display tasks and threads"),
};
+static int __init
+task_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(task_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(task_setup_shell,
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(task_setup, true),
+ INIT_OP_DEP(thread_setup, true));
+
#endif /* X15_SHELL */
-void __init
+static int __init
task_setup(void)
{
kmem_cache_init(&task_cache, "task", sizeof(struct task), 0, NULL, 0);
@@ -109,10 +122,14 @@ task_setup(void)
spinlock_init(&task_list_lock);
task_init(kernel_task, "x15", kernel_map);
list_insert_head(&task_list, &kernel_task->node);
-
- SHELL_REGISTER_CMDS(task_shell_cmds);
+ return 0;
}
+INIT_OP_DEFINE(task_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(spinlock_setup, true),
+ INIT_OP_DEP(vm_map_setup, true));
+
int
task_create(struct task **taskp, const char *name)
{
diff --git a/kern/task.h b/kern/task.h
index 591e8d7e..1711fbee 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -19,6 +19,7 @@
#define _KERN_TASK_H
#include <kern/atomic.h>
+#include <kern/init.h>
#include <kern/list.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
@@ -75,11 +76,6 @@ task_get_vm_map(const struct task *task)
}
/*
- * Initialize the task module.
- */
-void task_setup(void);
-
-/*
* Create a task.
*/
int task_create(struct task **taskp, const char *name);
@@ -119,4 +115,11 @@ struct thread * task_lookup_thread(struct task *task, const char *name);
*/
void task_info(struct task *task);
+/*
+ * This init operation provides :
+ * - task creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(task_setup);
+
#endif /* _KERN_TASK_H */
diff --git a/kern/thread.c b/kern/thread.c
index a48a08a9..976b464f 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -1687,12 +1687,10 @@ thread_reset_real_priority(struct thread *thread)
}
static void __init
-thread_bootstrap_common(unsigned int cpu)
+thread_init_booter(unsigned int cpu)
{
struct thread *booter;
- cpumap_set(&thread_active_runqs, cpu);
-
/* Initialize only what's needed during bootstrap */
booter = &thread_booters[cpu];
booter->nr_refs = 0; /* Make sure booters aren't destroyed */
@@ -1708,10 +1706,20 @@ thread_bootstrap_common(unsigned int cpu)
booter->task = kernel_task;
snprintf(booter->name, sizeof(booter->name),
THREAD_KERNEL_PREFIX "thread_boot/%u", cpu);
- thread_runq_init(percpu_ptr(thread_runq, cpu), cpu, booter);
}
-void __init
+static int __init
+thread_setup_booter(void)
+{
+ tcb_set_current(&thread_booters[0].tcb);
+ thread_init_booter(0);
+ return 0;
+}
+
+INIT_OP_DEFINE(thread_setup_booter,
+ INIT_OP_DEP(tcb_setup, true));
+
+static int __init
thread_bootstrap(void)
{
cpumap_zero(&thread_active_runqs);
@@ -1719,15 +1727,14 @@ thread_bootstrap(void)
thread_fs_highest_round = THREAD_FS_INITIAL_ROUND;
- tcb_set_current(&thread_booters[0].tcb);
- thread_bootstrap_common(0);
+ cpumap_set(&thread_active_runqs, 0);
+ thread_runq_init(cpu_local_ptr(thread_runq), 0, &thread_booters[0]);
+ return 0;
}
-void __init
-thread_ap_bootstrap(void)
-{
- tcb_set_current(&thread_booters[cpu_id()].tcb);
-}
+INIT_OP_DEFINE(thread_bootstrap,
+ INIT_OP_DEP(syscnt_setup, true),
+ INIT_OP_DEP(thread_setup_booter, true));
void
thread_main(void (*fn)(void *), void *arg)
@@ -2292,15 +2299,37 @@ static struct shell_cmd thread_shell_cmds[] = {
"display the stack trace of a given thread"),
};
+static int __init
+thread_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(thread_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(thread_setup_shell,
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(task_setup, true),
+ INIT_OP_DEP(thread_setup, true));
+
#endif /* X15_SHELL */
-void __init
+static void __init
+thread_setup_common(unsigned int cpu)
+{
+ assert(cpu != 0);
+ cpumap_set(&thread_active_runqs, cpu);
+ thread_init_booter(cpu);
+ thread_runq_init(percpu_ptr(thread_runq, cpu), cpu, &thread_booters[cpu]);
+}
+
+static int __init
thread_setup(void)
{
int cpu;
for (cpu = 1; (unsigned int)cpu < cpu_count(); cpu++) {
- thread_bootstrap_common(cpu);
+ thread_setup_common(cpu);
}
kmem_cache_init(&thread_cache, "thread", sizeof(struct thread),
@@ -2316,7 +2345,28 @@ thread_setup(void)
thread_setup_runq(percpu_ptr(thread_runq, cpu));
}
- SHELL_REGISTER_CMDS(thread_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(thread_setup,
+ INIT_OP_DEP(cpumap_setup, true),
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(pmap_setup, true),
+ INIT_OP_DEP(sleepq_setup, true),
+ INIT_OP_DEP(task_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true),
+ INIT_OP_DEP(turnstile_setup, true),
+#ifdef X15_THREAD_STACK_GUARD
+ INIT_OP_DEP(vm_kmem_setup, true),
+ INIT_OP_DEP(vm_map_setup, true),
+ INIT_OP_DEP(vm_page_setup, true),
+#endif
+ );
+
+void __init
+thread_ap_setup(void)
+{
+ tcb_set_current(&thread_booters[cpu_id()].tcb);
}
int
diff --git a/kern/thread.h b/kern/thread.h
index 760bb5ec..f46f90c1 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -170,15 +170,6 @@ thread_attr_set_priority(struct thread_attr *attr, unsigned short priority)
}
/*
- * Early initialization of the thread module.
- *
- * These function make it possible to use migration and preemption control
- * operations (and in turn, spin locks) during bootstrap.
- */
-void thread_bootstrap(void);
-void thread_ap_bootstrap(void);
-
-/*
* Thread entry point.
*
* Loaded TCBs are expected to call this function with interrupts disabled.
@@ -186,9 +177,9 @@ void thread_ap_bootstrap(void);
void thread_main(void (*fn)(void *), void *arg);
/*
- * Initialize the thread module.
+ * Initialization of the thread module on APs.
*/
-void thread_setup(void);
+void thread_ap_setup(void);
/*
* Create a thread.
@@ -740,4 +731,24 @@ thread_get_specific(unsigned int key)
return thread_tsd_get(thread_self(), key);
}
+/*
+ * This init operation provides :
+ * - a dummy thread context for the BSP, allowing the use of thread_self()
+ */
+INIT_OP_DECLARE(thread_setup_booter);
+
+/*
+ * This init operation provides :
+ * - same as thread_setup_booter
+ * - BSP run queue initialization
+ */
+INIT_OP_DECLARE(thread_bootstrap);
+
+/*
+ * This init operation provides :
+ * - thread creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(thread_setup);
+
#endif /* _KERN_THREAD_H */
diff --git a/kern/turnstile.c b/kern/turnstile.c
index 24da2cd2..e724c1e9 100644
--- a/kern/turnstile.c
+++ b/kern/turnstile.c
@@ -500,7 +500,7 @@ turnstile_ctor(void *ptr)
turnstile->owner = NULL;
}
-void __init
+static int __init
turnstile_bootstrap(void)
{
unsigned int i;
@@ -508,15 +508,24 @@ turnstile_bootstrap(void)
for (i = 0; i < ARRAY_SIZE(turnstile_htable); i++) {
turnstile_bucket_init(&turnstile_htable[i]);
}
+
+ return 0;
}
-void __init
+INIT_OP_DEFINE(turnstile_bootstrap);
+
+static int __init
turnstile_setup(void)
{
kmem_cache_init(&turnstile_cache, "turnstile", sizeof(struct turnstile),
CPU_L1_SIZE, turnstile_ctor, 0);
+ return 0;
}
+INIT_OP_DEFINE(turnstile_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(turnstile_bootstrap, true));
+
struct turnstile *
turnstile_create(void)
{
diff --git a/kern/turnstile.h b/kern/turnstile.h
index 4bc8f74d..74512fa1 100644
--- a/kern/turnstile.h
+++ b/kern/turnstile.h
@@ -29,6 +29,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include <kern/init.h>
#include <kern/plist.h>
#include <kern/spinlock.h>
#include <kern/thread.h>
@@ -101,20 +102,6 @@ turnstile_td_get_turnstile(const struct turnstile_td *td)
void turnstile_td_propagate_priority(struct turnstile_td *td);
/*
- * Early initialization of the turnstile module.
- *
- * This module is initialized by architecture-specific code. It should
- * be one of the first modules to be initialized since it's used by
- * synchronization objects that may be accessed very early.
- */
-void turnstile_bootstrap(void);
-
-/*
- * Initialize the turnstile module.
- */
-void turnstile_setup(void);
-
-/*
* Create/destroy a turnstile.
*/
struct turnstile * turnstile_create(void);
@@ -197,4 +184,17 @@ void turnstile_signal(struct turnstile *turnstile);
void turnstile_own(struct turnstile *turnstile);
void turnstile_disown(struct turnstile *turnstile);
+/*
+ * This init operation provides :
+ * - ? TODO Review
+ */
+INIT_OP_DECLARE(turnstile_bootstrap);
+
+/*
+ * This init operation provides :
+ * - turnstile creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(turnstile_setup);
+
#endif /* _KERN_TURNSTILE_H */
diff --git a/kern/work.c b/kern/work.c
index 5021d6f8..9aa3f40e 100644
--- a/kern/work.c
+++ b/kern/work.c
@@ -472,7 +472,7 @@ work_thread_destroy(struct work_thread *worker)
kmem_cache_free(&work_thread_cache, worker);
}
-void __init
+static int __init
work_setup(void)
{
unsigned int i;
@@ -493,8 +493,20 @@ work_setup(void)
log_info("work: threads per pool (per-cpu/global): %u/%u, spare: %u",
percpu_var(work_pool_cpu_main.max_threads, 0),
work_pool_main.max_threads, WORK_THREADS_SPARE);
+
+ return 0;
}
+INIT_OP_DEFINE(work_setup,
+ INIT_OP_DEP(cpu_mp_probe, true),
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(spinlock_setup, true),
+ INIT_OP_DEP(syscnt_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true));
+
void
work_schedule(struct work *work, int flags)
{
diff --git a/kern/work.h b/kern/work.h
index 6e3876f0..a8df1f7e 100644
--- a/kern/work.h
+++ b/kern/work.h
@@ -26,6 +26,8 @@
#ifndef _KERN_WORK_H
#define _KERN_WORK_H
+#include <kern/init.h>
+
/*
* Work scheduling flags.
*/
@@ -134,11 +136,6 @@ work_init(struct work *work, work_fn_t fn)
}
/*
- * Initialize the work module.
- */
-void work_setup(void);
-
-/*
* Schedule work for deferred processing.
*
* This function may be called from interrupt context.
@@ -156,4 +153,11 @@ void work_queue_schedule(struct work_queue *queue, int flags);
*/
void work_report_periodic_event(void);
+/*
+ * This init operation provides :
+ * - works can be scheduled
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(work_setup);
+
#endif /* _KERN_WORK_H */
diff --git a/kern/xcall.c b/kern/xcall.c
index fffe2bc8..cccb9373 100644
--- a/kern/xcall.c
+++ b/kern/xcall.c
@@ -20,6 +20,7 @@
#include <stddef.h>
#include <kern/atomic.h>
+#include <kern/init.h>
#include <kern/macros.h>
#include <kern/percpu.h>
#include <kern/spinlock.h>
@@ -104,7 +105,7 @@ xcall_cpu_data_clear_recv_call(struct xcall_cpu_data *cpu_data)
xcall_cpu_data_set_recv_call(cpu_data, NULL);
}
-void
+static int __init
xcall_setup(void)
{
unsigned int i;
@@ -112,8 +113,15 @@ xcall_setup(void)
for (i = 0; i < cpu_count(); i++) {
xcall_cpu_data_init(percpu_ptr(xcall_cpu_data, i));
}
+
+ return 0;
}
+INIT_OP_DEFINE(xcall_setup,
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true),
+ INIT_OP_DEP(spinlock_setup, true));
+
void
xcall_call(xcall_fn_t fn, void *arg, unsigned int cpu)
{
diff --git a/kern/xcall.h b/kern/xcall.h
index 37c85867..27b6af25 100644
--- a/kern/xcall.h
+++ b/kern/xcall.h
@@ -30,11 +30,6 @@
typedef void (*xcall_fn_t)(void *arg);
/*
- * Initialize the xcall module.
- */
-void xcall_setup(void);
-
-/*
* Run the given cross-call function on a specific processor.
*
* The operation is completely synchronous, returning only when the function