diff options
author | Richard Braun <rbraun@sceen.net> | 2017-07-13 20:07:07 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-07-13 20:07:07 +0200 |
commit | dd78bb04876f66e967773d6dd03ea9534fe43cc2 (patch) | |
tree | 4d3080abf0cbcca7c058cba5cad2ed71e5d5e1e5 /kern | |
parent | 85292d947faabe8828810946c7a8067ef228d6fe (diff) |
Switch to initialization operations
Diffstat (limited to 'kern')
-rw-r--r-- | kern/arg.c | 24 | ||||
-rw-r--r-- | kern/arg.h | 14 | ||||
-rw-r--r-- | kern/console.c | 20 | ||||
-rw-r--r-- | kern/console.h | 19 | ||||
-rw-r--r-- | kern/cpumap.c | 9 | ||||
-rw-r--r-- | kern/cpumap.h | 13 | ||||
-rw-r--r-- | kern/intr.c | 24 | ||||
-rw-r--r-- | kern/intr.h | 20 | ||||
-rw-r--r-- | kern/kernel.c | 38 | ||||
-rw-r--r-- | kern/kmem.c | 33 | ||||
-rw-r--r-- | kern/kmem.h | 22 | ||||
-rw-r--r-- | kern/llsync.c | 14 | ||||
-rw-r--r-- | kern/llsync.h | 5 | ||||
-rw-r--r-- | kern/log.c | 36 | ||||
-rw-r--r-- | kern/log.h | 21 | ||||
-rw-r--r-- | kern/macros.h | 10 | ||||
-rw-r--r-- | kern/mutex.c | 11 | ||||
-rw-r--r-- | kern/mutex.h | 9 | ||||
-rw-r--r-- | kern/panic.c | 12 | ||||
-rw-r--r-- | kern/panic.h | 8 | ||||
-rw-r--r-- | kern/percpu.c | 22 | ||||
-rw-r--r-- | kern/percpu.h | 32 | ||||
-rw-r--r-- | kern/printf.c | 10 | ||||
-rw-r--r-- | kern/printf.h | 8 | ||||
-rw-r--r-- | kern/rdxtree.c | 7 | ||||
-rw-r--r-- | kern/rdxtree.h | 6 | ||||
-rw-r--r-- | kern/shell.c | 10 | ||||
-rw-r--r-- | kern/shell.h | 15 | ||||
-rw-r--r-- | kern/shutdown.c | 31 | ||||
-rw-r--r-- | kern/shutdown.h | 18 | ||||
-rw-r--r-- | kern/sleepq.c | 13 | ||||
-rw-r--r-- | kern/sleepq.h | 27 | ||||
-rw-r--r-- | kern/spinlock.c | 10 | ||||
-rw-r--r-- | kern/spinlock.h | 9 | ||||
-rw-r--r-- | kern/sref.c | 21 | ||||
-rw-r--r-- | kern/sref.h | 14 | ||||
-rw-r--r-- | kern/syscnt.c | 30 | ||||
-rw-r--r-- | kern/syscnt.h | 20 | ||||
-rw-r--r-- | kern/task.c | 23 | ||||
-rw-r--r-- | kern/task.h | 13 | ||||
-rw-r--r-- | kern/thread.c | 80 | ||||
-rw-r--r-- | kern/thread.h | 33 | ||||
-rw-r--r-- | kern/turnstile.c | 13 | ||||
-rw-r--r-- | kern/turnstile.h | 28 | ||||
-rw-r--r-- | kern/work.c | 14 | ||||
-rw-r--r-- | kern/work.h | 14 | ||||
-rw-r--r-- | kern/xcall.c | 10 | ||||
-rw-r--r-- | kern/xcall.h | 5 |
48 files changed, 630 insertions, 268 deletions
@@ -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) { @@ -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. @@ -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) { @@ -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 |