summaryrefslogtreecommitdiff
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
parent85292d947faabe8828810946c7a8067ef228d6fe (diff)
Switch to initialization operations
-rw-r--r--Makefrag.am4
-rw-r--r--arch/x86/machine/acpi.c29
-rw-r--r--arch/x86/machine/acpi.h12
-rw-r--r--arch/x86/machine/atcons.c17
-rw-r--r--arch/x86/machine/atcons.h25
-rw-r--r--arch/x86/machine/atkbd.c16
-rw-r--r--arch/x86/machine/atkbd.h7
-rw-r--r--arch/x86/machine/biosmem.c27
-rw-r--r--arch/x86/machine/biosmem.h21
-rw-r--r--arch/x86/machine/boot.c112
-rw-r--r--arch/x86/machine/boot.h42
-rw-r--r--arch/x86/machine/cga.c8
-rw-r--r--arch/x86/machine/cga.h11
-rw-r--r--arch/x86/machine/cpu.c58
-rw-r--r--arch/x86/machine/cpu.h44
-rw-r--r--arch/x86/machine/pmap.c42
-rw-r--r--arch/x86/machine/pmap.h31
-rw-r--r--arch/x86/machine/strace.c23
-rw-r--r--arch/x86/machine/strace.h14
-rw-r--r--arch/x86/machine/tcb.c9
-rw-r--r--arch/x86/machine/tcb.h7
-rw-r--r--arch/x86/machine/trap.c6
-rw-r--r--arch/x86/machine/trap.h13
-rw-r--r--arch/x86/machine/uart.c48
-rw-r--r--arch/x86/machine/uart.h21
-rw-r--r--arch/x86/x15.lds.S6
-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
-rw-r--r--vm/vm_kmem.c10
-rw-r--r--vm/vm_kmem.h12
-rw-r--r--vm/vm_map.c37
-rw-r--r--vm/vm_map.h19
-rw-r--r--vm/vm_object.c8
-rw-r--r--vm/vm_object.h12
-rw-r--r--vm/vm_page.c22
-rw-r--r--vm/vm_page.h22
-rw-r--r--vm/vm_setup.c40
-rw-r--r--vm/vm_setup.h28
84 files changed, 1171 insertions, 590 deletions
diff --git a/Makefrag.am b/Makefrag.am
index 6f4e6d4f..554a8b51 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -124,9 +124,7 @@ x15_SOURCES += \
vm/vm_object_types.h \
vm/vm_page.c \
vm/vm_page.h \
- vm/vm_prot.h \
- vm/vm_setup.c \
- vm/vm_setup.h
+ vm/vm_prot.h
x15_SOURCES += \
test/test.h
diff --git a/arch/x86/machine/acpi.c b/arch/x86/machine/acpi.c
index 93dc3258..dabc7f34 100644
--- a/arch/x86/machine/acpi.c
+++ b/arch/x86/machine/acpi.c
@@ -22,10 +22,12 @@
#include <string.h>
#include <kern/init.h>
+#include <kern/intr.h>
#include <kern/kmem.h>
#include <kern/log.h>
#include <kern/macros.h>
#include <kern/panic.h>
+#include <kern/percpu.h>
#include <kern/shutdown.h>
#include <machine/acpi.h>
#include <machine/biosmem.h>
@@ -661,7 +663,7 @@ acpi_load_fadt(void)
shutdown_register(&acpi_shutdown_ops, ACPI_SHUTDOWN_PRIORITY);
}
-int __init
+static int __init
acpi_setup(void)
{
struct acpi_rsdp rsdp;
@@ -670,18 +672,39 @@ acpi_setup(void)
error = acpi_find_rsdp(&rsdp);
if (error) {
- return error;
+ goto error;
}
error = acpi_copy_tables(&rsdp);
if (error) {
- return error;
+ goto error;
}
acpi_info();
acpi_load_madt();
acpi_load_fadt();
acpi_free_tables();
+
+ return 0;
+
+error:
+ /*
+ * For the sake of simplicity, it has been decided to ignore legacy
+ * specifications such as the multiprocessor specification, and use
+ * ACPI only. If ACPI is unavailable, consider the APIC system to
+ * be missing and fall back to using the legaxy XT-PIC.
+ */
+ pic_setup();
return 0;
}
+
+INIT_OP_DEFINE(acpi_setup,
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(intr_bootstrap, true),
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(percpu_setup, true),
+ INIT_OP_DEP(shutdown_bootstrap, true),
+ INIT_OP_DEP(trap_setup, true),
+ INIT_OP_DEP(vm_kmem_setup, true));
diff --git a/arch/x86/machine/acpi.h b/arch/x86/machine/acpi.h
index b767b9a2..1f65fd6f 100644
--- a/arch/x86/machine/acpi.h
+++ b/arch/x86/machine/acpi.h
@@ -22,12 +22,14 @@
#ifndef _X86_ACPI_H
#define _X86_ACPI_H
+#include <kern/init.h>
+
/*
- * Load ACPI information.
- *
- * Return 0 if successful (an error usually means hardware doesn't support
- * ACPI).
+ * This init operation provides :
+ * - Multiprocessor probing
+ * - registration of I/O APIC interrupt controllers
+ * - registration of ACPI shutdown operations
*/
-int acpi_setup(void);
+INIT_OP_DECLARE(acpi_setup);
#endif /* _X86_ACPI_H */
diff --git a/arch/x86/machine/atcons.c b/arch/x86/machine/atcons.c
index e1e14c62..0c35266f 100644
--- a/arch/x86/machine/atcons.c
+++ b/arch/x86/machine/atcons.c
@@ -129,21 +129,28 @@ static const struct console_ops atcons_ops = {
.putc = atcons_putc,
};
-void __init
+static int __init
atcons_bootstrap(void)
{
- cga_setup();
-
console_init(&atcons_console, "atcons", &atcons_ops);
console_register(&atcons_console);
+ return 0;
}
-void __init
+INIT_OP_DEFINE(atcons_bootstrap,
+ INIT_OP_DEP(cga_setup, true),
+ INIT_OP_DEP(console_bootstrap, true));
+
+static int __init
atcons_setup(void)
{
- atkbd_setup();
+ return 0;
}
+INIT_OP_DEFINE(atcons_setup,
+ INIT_OP_DEP(atcons_bootstrap, true),
+ INIT_OP_DEP(atkbd_setup, true));
+
void
atcons_intr(const char *s)
{
diff --git a/arch/x86/machine/atcons.h b/arch/x86/machine/atcons.h
index d6923df2..0d4893a6 100644
--- a/arch/x86/machine/atcons.h
+++ b/arch/x86/machine/atcons.h
@@ -21,17 +21,7 @@
#ifndef _X86_ATCONS_H
#define _X86_ATCONS_H
-/*
- * Early initialization of the atcons module.
- */
-void atcons_bootstrap(void);
-
-/*
- * Initialize the atcons module.
- *
- * This function enables keyboard interrupt handling.
- */
-void atcons_setup(void);
+#include <kern/init.h>
/*
* Console interrupt handler.
@@ -49,4 +39,17 @@ void atcons_bottom(void);
void atcons_right(void);
void atcons_up(void);
+/*
+ * This init operation provides :
+ * - CGA output through the console module
+ */
+INIT_OP_DECLARE(atcons_bootstrap);
+
+/*
+ * This init operation provides :
+ * - AT keyboard input through the console module
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(atcons_setup);
+
#endif /* _X86_ATCONS_H */
diff --git a/arch/x86/machine/atkbd.c b/arch/x86/machine/atkbd.c
index fd804269..59f8d681 100644
--- a/arch/x86/machine/atkbd.c
+++ b/arch/x86/machine/atkbd.c
@@ -843,7 +843,7 @@ atkbd_intr(void *arg)
return 0;
}
-void __init
+static int __init
atkbd_setup(void)
{
int error;
@@ -851,25 +851,31 @@ atkbd_setup(void)
error = atkbd_flush();
if (error) {
- return;
+ return 0;
}
error = atkbd_disable();
if (error) {
- return;
+ return 0;
}
error = intr_register(ATKBD_INTR1, atkbd_intr, NULL);
if (error) {
log_err("atkbd: unable to register interrupt handler");
- return;
+ return 0;
}
error = atkbd_enable();
if (error) {
- return;
+ return 0;
}
+
+ return 0;
}
+
+INIT_OP_DEFINE(atkbd_setup,
+ INIT_OP_DEP(atcons_bootstrap, true),
+ INIT_OP_DEP(intr_setup, true));
diff --git a/arch/x86/machine/atkbd.h b/arch/x86/machine/atkbd.h
index 0bed7ada..9efeefbf 100644
--- a/arch/x86/machine/atkbd.h
+++ b/arch/x86/machine/atkbd.h
@@ -21,9 +21,12 @@
#ifndef _X86_ATKBD_H
#define _X86_ATKBD_H
+#include <kern/init.h>
+
/*
- * Initialize the atkbd module.
+ * This init operation provides :
+ * - module fully initialized
*/
-void atkbd_setup(void);
+INIT_OP_DECLARE(atkbd_setup);
#endif /* _X86_ATKBD_H */
diff --git a/arch/x86/machine/biosmem.c b/arch/x86/machine/biosmem.c
index 64482c60..fc03614c 100644
--- a/arch/x86/machine/biosmem.c
+++ b/arch/x86/machine/biosmem.c
@@ -33,7 +33,6 @@
#include <machine/pmap.h>
#include <machine/pmem.h>
#include <machine/types.h>
-#include <vm/vm_kmem.h>
#include <vm/vm_page.h>
#define BIOSMEM_MAX_BOOT_DATA 64
@@ -234,9 +233,9 @@ biosmem_unregister_boot_data(phys_addr_t start, phys_addr_t end)
biosmem_nr_boot_data--;
- boot_memmove(&biosmem_boot_data_array[i],
- &biosmem_boot_data_array[i + 1],
- (biosmem_nr_boot_data - i) * sizeof(*biosmem_boot_data_array));
+ memmove(&biosmem_boot_data_array[i],
+ &biosmem_boot_data_array[i + 1],
+ (biosmem_nr_boot_data - i) * sizeof(*biosmem_boot_data_array));
}
static void __boot
@@ -813,7 +812,7 @@ biosmem_load_zone(struct biosmem_zone *zone, uint64_t max_phys_end)
if (phys_end > max_phys_end) {
if (max_phys_end <= phys_start) {
log_warning("biosmem: zone %s physically unreachable, "
- "not loaded", vm_page_zone_name(zone_index));
+ "not loaded", vm_page_zone_name(zone_index));
return;
}
@@ -847,7 +846,7 @@ biosmem_load_zone(struct biosmem_zone *zone, uint64_t max_phys_end)
}
}
-void __init
+static int __init
biosmem_setup(void)
{
uint64_t max_phys_end;
@@ -870,8 +869,14 @@ biosmem_setup(void)
zone = &biosmem_zones[i];
biosmem_load_zone(zone, max_phys_end);
}
+
+ return 0;
}
+INIT_OP_DEFINE(biosmem_setup,
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(log_setup, true));
+
static void __init
biosmem_unregister_temporary_boot_data(void)
{
@@ -925,7 +930,7 @@ biosmem_free_usable_entry(phys_addr_t start, phys_addr_t end)
}
}
-void __init
+static int __init
biosmem_free_usable(void)
{
struct biosmem_map_entry *entry;
@@ -963,4 +968,12 @@ biosmem_free_usable(void)
biosmem_free_usable_entry(start, end);
}
+
+ return 0;
}
+
+INIT_OP_DEFINE(biosmem_free_usable,
+ INIT_OP_DEP(boot_save_data, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(vm_page_setup, true));
diff --git a/arch/x86/machine/biosmem.h b/arch/x86/machine/biosmem.h
index d877af4c..2a701dec 100644
--- a/arch/x86/machine/biosmem.h
+++ b/arch/x86/machine/biosmem.h
@@ -20,6 +20,7 @@
#include <stdbool.h>
+#include <kern/init.h>
#include <machine/multiboot.h>
#include <machine/types.h>
@@ -53,9 +54,9 @@
* Once all boot data have been registered, the user can set up the
* early page allocator.
*
- * If the range is marked temporary, it will be unregistered when
- * biosmem_free_usable() is called, so that pages that used to store
- * these boot data may be released to the VM system.
+ * If the range is marked temporary, it will be unregistered once
+ * the boot data have been saved/consumed so that their backing
+ * pages are loaded into the VM system.
*
* This function is called before paging is enabled.
*/
@@ -102,17 +103,9 @@ const void * biosmem_get_bda(void);
phys_addr_t biosmem_directmap_end(void);
/*
- * Set up physical memory based on the information obtained during bootstrap
- * and load it in the VM system.
+ * This init operation provides :
+ * - heaps of physical memory are loaded by the VM system
*/
-void biosmem_setup(void);
-
-/*
- * Free all usable memory.
- *
- * This function releases all pages that aren't used by boot data and have
- * not already been loaded into the VM system.
- */
-void biosmem_free_usable(void);
+INIT_OP_DECLARE(biosmem_setup);
#endif /* _X86_BIOSMEM_H */
diff --git a/arch/x86/machine/boot.c b/arch/x86/machine/boot.c
index 571b04f6..25e92ff6 100644
--- a/arch/x86/machine/boot.c
+++ b/arch/x86/machine/boot.c
@@ -43,27 +43,19 @@
*/
#include <stdalign.h>
-#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <kern/arg.h>
-#include <kern/console.h>
#include <kern/init.h>
-#include <kern/intr.h>
#include <kern/kmem.h>
#include <kern/kernel.h>
#include <kern/log.h>
#include <kern/macros.h>
#include <kern/panic.h>
-#include <kern/percpu.h>
-#include <kern/shutdown.h>
-#include <kern/sleepq.h>
-#include <kern/sref.h>
-#include <kern/syscnt.h>
#include <kern/thread.h>
-#include <kern/turnstile.h>
+#include <machine/acpi.h>
#include <machine/atcons.h>
#include <machine/biosmem.h>
#include <machine/boot.h>
@@ -74,10 +66,8 @@
#include <machine/page.h>
#include <machine/pmap.h>
#include <machine/strace.h>
-#include <machine/trap.h>
#include <machine/uart.h>
#include <vm/vm_kmem.h>
-#include <vm/vm_setup.h>
alignas(CPU_DATA_ALIGN) char boot_stack[BOOT_STACK_SIZE] __bootdata;
alignas(CPU_DATA_ALIGN) char boot_ap_stack[BOOT_STACK_SIZE] __bootdata;
@@ -358,8 +348,8 @@ boot_setup_paging(struct multiboot_raw_info *mbi, unsigned long eax)
return pmap_setup_paging();
}
-static void __init
-boot_log_version(void)
+void __init
+boot_log_info(void)
{
log_info(KERNEL_NAME "/" QUOTE(X15_X86_MACHINE) " " KERNEL_VERSION
#ifdef X15_X86_PAE
@@ -480,46 +470,24 @@ boot_save_mods(void)
* the boot loader. Once the boot data are managed as kernel buffers, their
* backing pages can be freed.
*/
-static void __init
+static int __init
boot_save_data(void)
{
boot_mbi.flags = boot_raw_mbi.flags;
boot_save_mods();
- strace_setup(&boot_raw_mbi);
+ return 0;
}
+INIT_OP_DEFINE(boot_save_data,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(panic_setup, true),
+ INIT_OP_DEP(vm_kmem_setup, true));
+
void __init
boot_main(void)
{
- log_setup();
- arg_setup(boot_tmp_cmdline);
- sleepq_bootstrap();
- turnstile_bootstrap();
- syscnt_setup();
- percpu_bootstrap();
- trap_setup();
- cpu_setup();
- thread_bootstrap();
- boot_log_version();
- arg_log_info();
- console_setup();
- atcons_bootstrap();
- uart_bootstrap();
- printf_setup();
- uart_info();
- pmap_bootstrap();
- sref_bootstrap();
- cpu_check(cpu_current());
- cpu_info(cpu_current());
- biosmem_setup();
- vm_setup();
- boot_save_data();
- biosmem_free_usable();
- shutdown_setup();
- intr_setup();
- cpu_mp_probe();
- atcons_setup();
- uart_setup();
+ arg_set_cmdline(boot_tmp_cmdline);
+ strace_set_mbi(&boot_raw_mbi);
kernel_main();
/* Never reached */
@@ -529,9 +497,61 @@ void __init
boot_ap_main(void)
{
cpu_ap_setup();
- thread_ap_bootstrap();
- pmap_ap_bootstrap();
+ thread_ap_setup();
+ pmap_ap_setup();
kernel_ap_main();
/* Never reached */
}
+
+/*
+ * Init operation aliases.
+ */
+
+static int __init
+boot_bootstrap_console(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(boot_bootstrap_console,
+ INIT_OP_DEP(atcons_bootstrap, true),
+ INIT_OP_DEP(uart_bootstrap, true));
+
+static int __init
+boot_setup_console(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(boot_setup_console,
+ INIT_OP_DEP(atcons_setup, true),
+ INIT_OP_DEP(uart_setup, true));
+
+static int __init
+boot_load_vm_page_zones(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(boot_load_vm_page_zones,
+ INIT_OP_DEP(biosmem_setup, true));
+
+static int __init
+boot_setup_intr(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(boot_setup_intr,
+ INIT_OP_DEP(acpi_setup, true));
+
+static int __init
+boot_setup_shutdown(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(boot_setup_shutdown,
+ INIT_OP_DEP(acpi_setup, true),
+ INIT_OP_DEP(cpu_setup_shutdown, true));
diff --git a/arch/x86/machine/boot.h b/arch/x86/machine/boot.h
index 8c590c64..c85c2648 100644
--- a/arch/x86/machine/boot.h
+++ b/arch/x86/machine/boot.h
@@ -60,6 +60,7 @@
#ifndef __ASSEMBLER__
+#include <kern/init.h>
#include <machine/multiboot.h>
#include <machine/pmap.h>
@@ -122,6 +123,47 @@ void boot_main(void);
*/
void boot_ap_main(void);
+/*
+ * Log kernel version and other architecture-specific information.
+ */
+void boot_log_info(void);
+
+/*
+ * This init operation provides :
+ * - boot data are saved
+ */
+INIT_OP_DECLARE(boot_save_data);
+
+/*
+ * This init operation provides :
+ * - all console devices are bootstrapped
+ */
+INIT_OP_DECLARE(boot_bootstrap_console);
+
+/*
+ * This init operation provides :
+ * - all console devices are fully initialized
+ */
+INIT_OP_DECLARE(boot_setup_console);
+
+/*
+ * This init operation provides :
+ * - physical memory has been loaded to the VM system
+ */
+INIT_OP_DECLARE(boot_load_vm_page_zones);
+
+/*
+ * This init operation provides :
+ * - all interrupt controllers have been registered
+ */
+INIT_OP_DECLARE(boot_setup_intr);
+
+/*
+ * This init operation provides :
+ * - all shutdown operations have been registered
+ */
+INIT_OP_DECLARE(boot_setup_shutdown);
+
#endif /* __ASSEMBLER__ */
#endif /* _X86_BOOT_H */
diff --git a/arch/x86/machine/cga.c b/arch/x86/machine/cga.c
index 3ce4032c..b519ba1f 100644
--- a/arch/x86/machine/cga.c
+++ b/arch/x86/machine/cga.c
@@ -20,10 +20,10 @@
#include <stdint.h>
#include <string.h>
+#include <kern/console.h>
#include <kern/error.h>
#include <kern/init.h>
#include <kern/cbuf.h>
-#include <kern/console.h>
#include <kern/macros.h>
#include <machine/io.h>
#include <machine/cga.h>
@@ -448,15 +448,17 @@ cga_setup_misc_out(void)
}
}
-void __init
+static int __init
cga_setup(void)
{
cga_memory = (void *)vm_page_direct_va(CGA_MEMORY);
-
cga_setup_misc_out();
cga_bbuf_init(&cga_bbuf, cga_get_cursor_position());
+ return 0;
}
+INIT_OP_DEFINE(cga_setup);
+
void
cga_cursor_left(void)
{
diff --git a/arch/x86/machine/cga.h b/arch/x86/machine/cga.h
index 2310bc91..2708ec4d 100644
--- a/arch/x86/machine/cga.h
+++ b/arch/x86/machine/cga.h
@@ -21,10 +21,7 @@
#ifndef _X86_CGA_H
#define _X86_CGA_H
-/*
- * Initialize the cga module.
- */
-void cga_setup(void);
+#include <kern/init.h>
/*
* Append a character to the CGA screen.
@@ -37,4 +34,10 @@ void cga_putc(char c);
void cga_cursor_left(void);
void cga_cursor_right(void);
+/*
+ * This init operation provides :
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(cga_setup);
+
#endif /* _X86_CGA_H */
diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c
index debacf0c..98d3680e 100644
--- a/arch/x86/machine/cpu.c
+++ b/arch/x86/machine/cpu.c
@@ -124,7 +124,7 @@ struct cpu cpu_desc __percpu;
/*
* Number of active processors.
*/
-unsigned int cpu_nr_active __read_mostly;
+unsigned int cpu_nr_active __read_mostly = 1;
/*
* Processor frequency, assumed fixed and equal on all processors.
@@ -557,7 +557,7 @@ cpu_measure_freq(void)
cpu_freq = (end - start) / (1000000 / CPU_FREQ_CAL_DELAY);
}
-void __init
+static int __init
cpu_setup(void)
{
struct cpu *cpu;
@@ -566,18 +566,23 @@ cpu_setup(void)
cpu_preinit(cpu, 0, CPU_INVALID_APIC_ID);
cpu->double_fault_stack = cpu_double_fault_stack; /* XXX */
cpu_init(cpu);
- cpu_nr_active = 1;
cpu_measure_freq();
+
+ return 0;
}
+INIT_OP_DEFINE(cpu_setup,
+ INIT_OP_DEP(percpu_bootstrap, true),
+ INIT_OP_DEP(trap_setup, true));
+
static void __init
cpu_panic_on_missing_feature(const char *feature)
{
panic("cpu: %s feature missing", feature);
}
-void __init
+static void __init
cpu_check(const struct cpu *cpu)
{
if (!(cpu->features2 & CPU_FEATURE2_FPU)) {
@@ -597,8 +602,19 @@ cpu_check(const struct cpu *cpu)
#endif
}
+static int __init
+cpu_check_bsp(void)
+{
+ cpu_check(cpu_current());
+ return 0;
+}
+
+INIT_OP_DEFINE(cpu_check_bsp,
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(panic_setup, true));
+
void
-cpu_info(const struct cpu *cpu)
+cpu_log_info(const struct cpu *cpu)
{
log_info("cpu%u: %s, type %u, family %u, model %u, stepping %u",
cpu->id, cpu->vendor_id, cpu->type, cpu->family, cpu->model,
@@ -657,30 +673,32 @@ static struct shutdown_ops cpu_shutdown_ops = {
.reset = cpu_shutdown_reset,
};
-void __init
+static int __init
cpu_mp_probe(void)
{
- int error;
-
- error = acpi_setup();
-
- if (error) {
- /*
- * For the sake of simplicity, it has been decided to ignore legacy
- * specifications such as the multiprocessor specification, and use
- * ACPI only. If ACPI is unavailable, consider the APIC system to
- * be missing and fall back to using the legaxy XT-PIC.
- */
- pic_setup();
- }
-
log_info("cpu: %u processor(s) configured", cpu_count());
+ return 0;
+}
+
+INIT_OP_DEFINE(cpu_mp_probe,
+ INIT_OP_DEP(acpi_setup, true),
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(log_setup, true));
+static int __init
+cpu_setup_shutdown(void)
+{
if (cpu_count() == 1) {
shutdown_register(&cpu_shutdown_ops, CPU_SHUTDOWN_PRIORITY);
}
+
+ return 0;
}
+INIT_OP_DEFINE(cpu_setup_shutdown,
+ INIT_OP_DEP(cpu_mp_probe, true),
+ INIT_OP_DEP(shutdown_bootstrap, true));
+
void __init
cpu_mp_setup(void)
{
diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h
index ee4eb18b..39f17f84 100644
--- a/arch/x86/machine/cpu.h
+++ b/arch/x86/machine/cpu.h
@@ -127,6 +127,7 @@
#include <stdint.h>
#include <stdnoreturn.h>
+#include <kern/init.h>
#include <kern/macros.h>
#include <kern/percpu.h>
#include <machine/lapic.h>
@@ -614,24 +615,16 @@ void * cpu_get_boot_stack(void);
/*
* Install an interrupt handler in the IDT.
+ *
+ * These functions may be called before the cpu module is initialized.
*/
void cpu_idt_set_gate(unsigned int vector, void (*isr)(void));
void cpu_idt_set_double_fault(void (*isr)(void));
/*
- * Set up the cpu module.
- */
-void cpu_setup(void);
-
-/*
- * Make sure the CPU has some required features.
- */
-void cpu_check(const struct cpu *cpu);
-
-/*
- * Display processor information.
+ * Log processor information.
*/
-void cpu_info(const struct cpu *cpu);
+void cpu_log_info(const struct cpu *cpu);
/*
* Register the presence of a local APIC.
@@ -639,13 +632,6 @@ void cpu_info(const struct cpu *cpu);
void cpu_mp_register_lapic(unsigned int apic_id, int is_bsp);
/*
- * Probe application processors.
- *
- * On return, cpu_count() gives the actual number of managed processors.
- */
-void cpu_mp_probe(void);
-
-/*
* Start application processors.
*
* The x86 architecture uses per-CPU page tables, which are created as a
@@ -696,6 +682,26 @@ cpu_send_thread_schedule(unsigned int cpu)
*/
void cpu_thread_schedule_intr(struct trap_frame *frame);
+/*
+ * This init operation provides :
+ * - initialization of the BSP structure.
+ * - cpu_delay()
+ * - cpu_local_ptr() and cpu_local_var()
+ */
+INIT_OP_DECLARE(cpu_setup);
+
+/*
+ * This init operation provides :
+ * - cpu_count()
+ */
+INIT_OP_DECLARE(cpu_mp_probe);
+
+/*
+ * This init operation provides :
+ * - cpu shutdown operations registered
+ */
+INIT_OP_DECLARE(cpu_setup_shutdown);
+
#endif /* __ASSEMBLER__ */
#endif /* _X86_CPU_H */
diff --git a/arch/x86/machine/pmap.c b/arch/x86/machine/pmap.c
index 93b68758..7ab70bfd 100644
--- a/arch/x86/machine/pmap.c
+++ b/arch/x86/machine/pmap.c
@@ -828,7 +828,7 @@ pmap_syncer_init(struct pmap_syncer *syncer, unsigned int cpu)
syscnt_register(&syncer->sc_update_protects, name);
}
-void __init
+static int __init
pmap_bootstrap(void)
{
struct pmap_cpu_table *cpu_table;
@@ -864,20 +864,17 @@ pmap_bootstrap(void)
if (cpu_has_global_pages()) {
pmap_setup_global_pages();
}
-}
-void __init
-pmap_ap_bootstrap(void)
-{
- cpu_local_assign(pmap_current_ptr, kernel_pmap);
-
- if (cpu_has_global_pages()) {
- cpu_enable_global_pages();
- } else {
- cpu_tlb_flush();
- }
+ return 0;
}
+INIT_OP_DEFINE(pmap_bootstrap,
+ INIT_OP_DEP(cpu_setup, true),
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(spinlock_setup, true),
+ INIT_OP_DEP(syscnt_setup, true),
+ INIT_OP_DEP(thread_bootstrap, true));
+
static void __init
pmap_setup_set_ptp_type(phys_addr_t ptp_pa, unsigned int index,
unsigned int level)
@@ -906,7 +903,7 @@ pmap_setup_fix_ptps(void)
pmap_setup_set_ptp_type);
}
-void __init
+static int __init
pmap_setup(void)
{
pmap_setup_fix_ptps();
@@ -914,6 +911,25 @@ pmap_setup(void)
kmem_cache_init(&pmap_update_oplist_cache, "pmap_update_oplist",
sizeof(struct pmap_update_oplist), CPU_L1_SIZE,
pmap_update_oplist_ctor, 0);
+ return 0;
+}
+
+INIT_OP_DEFINE(pmap_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(pmap_bootstrap, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
+void __init
+pmap_ap_setup(void)
+{
+ cpu_local_assign(pmap_current_ptr, kernel_pmap);
+
+ if (cpu_has_global_pages()) {
+ cpu_enable_global_pages();
+ } else {
+ cpu_tlb_flush();
+ }
}
static void __init
diff --git a/arch/x86/machine/pmap.h b/arch/x86/machine/pmap.h
index 84042583..114dcdac 100644
--- a/arch/x86/machine/pmap.h
+++ b/arch/x86/machine/pmap.h
@@ -165,6 +165,7 @@
#include <stdint.h>
#include <kern/cpumap.h>
+#include <kern/init.h>
#include <kern/list.h>
#include <kern/mutex.h>
#include <kern/thread.h>
@@ -203,22 +204,9 @@ pmap_pte_t * pmap_setup_paging(void);
pmap_pte_t * pmap_ap_setup_paging(void);
/*
- * Early initialization of the pmap module.
+ * Initialize the pmap module on APs.
*/
-void pmap_bootstrap(void);
-
-/*
- * Early initialization of the MMU on APs.
- */
-void pmap_ap_bootstrap(void);
-
-/*
- * Set up the pmap module.
- *
- * This function should only be called by the VM system, once kernel
- * allocations can be performed safely.
- */
-void pmap_setup(void);
+void pmap_ap_setup(void);
/*
* Set up the pmap module for multiprocessor operations.
@@ -330,6 +318,19 @@ pmap_current(void)
return cpu_local_read(pmap_current_ptr);
}
+/*
+ * This init operation provides :
+ * - kernel pmap operations
+ */
+INIT_OP_DECLARE(pmap_bootstrap);
+
+/*
+ * This init operation provides :
+ * - user pmap creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(pmap_setup);
+
#endif /* __ASSEMBLER__ */
#endif /* _X86_PMAP_H */
diff --git a/arch/x86/machine/strace.c b/arch/x86/machine/strace.c
index 4b7e7438..cfb237e1 100644
--- a/arch/x86/machine/strace.c
+++ b/arch/x86/machine/strace.c
@@ -36,6 +36,8 @@
#define STRACE_ADDR_FORMAT "%#010lx"
#endif /* __LP64__ */
+static const struct multiboot_raw_info *strace_mbi __initdata;
+
static struct elf_sym *strace_symtab __read_mostly;
static struct elf_sym *strace_symtab_end __read_mostly;
static char *strace_strtab __read_mostly;
@@ -173,14 +175,23 @@ strace_lookup_section(const struct multiboot_raw_info *mbi, const void *table,
}
void __init
-strace_setup(const struct multiboot_raw_info *mbi)
+strace_set_mbi(const struct multiboot_raw_info *mbi)
+{
+ strace_mbi = mbi;
+}
+
+static int __init
+strace_setup(void)
{
const struct elf_shdr *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
+ const struct multiboot_raw_info *mbi;
uintptr_t map_addr, shstrtab_map_addr;
size_t size, map_size, shstrtab_map_size;
const char *shstrtab;
const void *table;
+ mbi = strace_mbi;
+
if (!(mbi->flags & MULTIBOOT_LOADER_SHDR) || (mbi->shdr_num == 0)) {
goto no_syms;
}
@@ -236,7 +247,7 @@ strace_setup(const struct multiboot_raw_info *mbi)
vm_kmem_unmap_pa(shstrtab_map_addr, shstrtab_map_size);
vm_kmem_unmap_pa(map_addr, map_size);
- return;
+ return 0;
error_strtab:
kmem_free(strace_symtab, symtab_hdr->size);
@@ -251,4 +262,12 @@ no_syms:
strace_symtab = NULL;
strace_symtab_end = NULL;
strace_strtab = NULL;
+ return 0;
}
+
+INIT_OP_DEFINE(strace_setup,
+ INIT_OP_DEP(kmem_setup, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(pmap_bootstrap, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(vm_kmem_setup, true));
diff --git a/arch/x86/machine/strace.h b/arch/x86/machine/strace.h
index 66aa18b7..2f686a07 100644
--- a/arch/x86/machine/strace.h
+++ b/arch/x86/machine/strace.h
@@ -21,6 +21,7 @@
#ifndef _X86_STRACE_H
#define _X86_STRACE_H
+#include <kern/init.h>
#include <kern/macros.h>
#include <machine/multiboot.h>
@@ -45,10 +46,17 @@ strace_dump(void)
}
/*
- * Setup the stack tracing module.
+ * Pass the multiboot information structure.
*
- * If available, the symbol table is extracted from the boot data.
+ * If available, the symbol table is extracted from the boot data, when
+ * the strace module is initialized.
*/
-void strace_setup(const struct multiboot_raw_info *mbi);
+void strace_set_mbi(const struct multiboot_raw_info *mbi);
+
+/*
+ * This init operation provides :
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(strace_setup);
#endif /* _X86_STRACE_H */
diff --git a/arch/x86/machine/tcb.c b/arch/x86/machine/tcb.c
index fb31a172..b54945c7 100644
--- a/arch/x86/machine/tcb.c
+++ b/arch/x86/machine/tcb.c
@@ -104,3 +104,12 @@ tcb_trace(const struct tcb *tcb)
{
strace_show((uintptr_t)tcb_context_restore, tcb->bp);
}
+
+static int __init
+tcb_setup(void)
+{
+ return 0;
+}
+
+INIT_OP_DEFINE(tcb_setup,
+ INIT_OP_DEP(cpu_setup, true));
diff --git a/arch/x86/machine/tcb.h b/arch/x86/machine/tcb.h
index 9c69a5ee..9107f7c4 100644
--- a/arch/x86/machine/tcb.h
+++ b/arch/x86/machine/tcb.h
@@ -25,6 +25,7 @@
#include <stdint.h>
#include <stdnoreturn.h>
+#include <kern/init.h>
#include <machine/cpu.h>
#include <machine/page.h>
@@ -95,4 +96,10 @@ tcb_switch(struct tcb *prev, struct tcb *next)
*/
void tcb_trace(const struct tcb *tcb);
+/*
+ * This init operation provides :
+ * - current TCB handling
+ */
+INIT_OP_DECLARE(tcb_setup);
+
#endif /* _X86_TCB_H */
diff --git a/arch/x86/machine/trap.c b/arch/x86/machine/trap.c
index 1580fa53..878f20c9 100644
--- a/arch/x86/machine/trap.c
+++ b/arch/x86/machine/trap.c
@@ -171,7 +171,7 @@ trap_default(struct trap_frame *frame)
cpu_halt();
}
-void __init
+static int __init
trap_setup(void)
{
size_t i;
@@ -213,8 +213,12 @@ trap_setup(void)
trap_install(TRAP_LAPIC_TIMER, TRAP_HF_INTR, lapic_timer_intr);
trap_install(TRAP_LAPIC_ERROR, TRAP_HF_INTR, lapic_error_intr);
trap_install(TRAP_LAPIC_SPURIOUS, TRAP_HF_INTR, lapic_spurious_intr);
+
+ return 0;
}
+INIT_OP_DEFINE(trap_setup);
+
void
trap_main(struct trap_frame *frame)
{
diff --git a/arch/x86/machine/trap.h b/arch/x86/machine/trap.h
index f8d0a16f..699f19e7 100644
--- a/arch/x86/machine/trap.h
+++ b/arch/x86/machine/trap.h
@@ -77,6 +77,7 @@
#include <stdint.h>
#include <stdio.h>
+#include <kern/init.h>
#include <kern/macros.h>
#ifdef __LP64__
@@ -144,11 +145,6 @@ trap_trigger_double_fault(void)
}
/*
- * Set up the trap module.
- */
-void trap_setup(void);
-
-/*
* Unified trap entry point.
*/
void trap_main(struct trap_frame *frame);
@@ -177,6 +173,13 @@ void trap_stack_show(struct trap_frame *frame);
*/
void * trap_get_interrupt_stack(const struct trap_frame *frame);
+/*
+ * This init operation provides :
+ * - initialization of all IDT entries and trap handlers
+ * - double fault exception support
+ */
+INIT_OP_DECLARE(trap_setup);
+
#endif /* __ASSEMBLER__ */
#endif /* _X86_TRAP_H */
diff --git a/arch/x86/machine/uart.c b/arch/x86/machine/uart.c
index cdb49a90..10a32886 100644
--- a/arch/x86/machine/uart.c
+++ b/arch/x86/machine/uart.c
@@ -407,7 +407,23 @@ uart_init(struct uart *uart, uint16_t port, uint16_t intr)
console_register(&uart->console);
}
-void __init
+static void __init
+uart_log_info(void)
+{
+ const struct uart *uart;
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(uart_devs); i++) {
+ uart = uart_get_dev(i);
+
+ if (uart->port != 0) {
+ log_info("uart%zu: port:%#x irq:%u", i, (unsigned int)uart->port,
+ (unsigned int)uart->intr);
+ }
+ }
+}
+
+static int __init
uart_bootstrap(void)
{
const uint16_t *ptr;
@@ -422,9 +438,17 @@ uart_bootstrap(void)
uart_init(uart_get_dev(i), ptr[i], uart_intrs[i]);
}
+
+ uart_log_info();
+ return 0;
}
-void __init
+INIT_OP_DEFINE(uart_bootstrap,
+ INIT_OP_DEP(arg_setup, true),
+ INIT_OP_DEP(console_bootstrap, true),
+ INIT_OP_DEP(log_setup, true));
+
+static int __init
uart_setup(void)
{
struct uart *uart;
@@ -439,20 +463,10 @@ uart_setup(void)
uart_enable_intr(uart);
}
-}
-void __init
-uart_info(void)
-{
- const struct uart *uart;
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(uart_devs); i++) {
- uart = uart_get_dev(i);
-
- if (uart->port != 0) {
- log_info("uart%zu: port:%#x irq:%u", i, (unsigned int)uart->port,
- (unsigned int)uart->intr);
- }
- }
+ return 0;
}
+
+INIT_OP_DEFINE(uart_setup,
+ INIT_OP_DEP(intr_setup, true),
+ INIT_OP_DEP(uart_bootstrap, true));
diff --git a/arch/x86/machine/uart.h b/arch/x86/machine/uart.h
index 60b195c6..0054da86 100644
--- a/arch/x86/machine/uart.h
+++ b/arch/x86/machine/uart.h
@@ -21,24 +21,19 @@
#ifndef _X86_UART_H
#define _X86_UART_H
-/*
- * Early initialization of the uart module.
- *
- * Devices may only be used to report diagnostics until initialization
- * is completed.
- */
-void uart_bootstrap(void);
+#include <kern/init.h>
/*
- * Initialize the uart module.
- *
- * On return, devices may be used for both input and output, using interrupts.
+ * This init operation provides :
+ * - UART output through the console module
*/
-void uart_setup(void);
+INIT_OP_DECLARE(uart_bootstrap);
/*
- * Display device information.
+ * This init operation provides :
+ * - UART input through the console module
+ * - module fully initialized
*/
-void uart_info(void);
+INIT_OP_DECLARE(uart_setup);
#endif /* _X86_UART_H */
diff --git a/arch/x86/x15.lds.S b/arch/x86/x15.lds.S
index 0bf809b9..352ebf4a 100644
--- a/arch/x86/x15.lds.S
+++ b/arch/x86/x15.lds.S
@@ -44,6 +44,12 @@ SECTIONS
.init ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.init))) {
*(.init.text)
*(.init.data)
+
+ . = ALIGN(64);
+ _init_ops = .;
+ *(.init.ops)
+ _init_ops_end = .;
+
} : init
. = ALIGN(PAGE_SIZE);
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
diff --git a/vm/vm_kmem.c b/vm/vm_kmem.c
index da372b00..dc204f85 100644
--- a/vm/vm_kmem.c
+++ b/vm/vm_kmem.c
@@ -22,7 +22,6 @@
#include <kern/cpumap.h>
#include <kern/init.h>
#include <kern/macros.h>
-#include <kern/panic.h>
#include <machine/page.h>
#include <machine/pmap.h>
#include <machine/types.h>
@@ -49,15 +48,22 @@ vm_kmem_offset(uintptr_t va)
return va - PMAP_MIN_KMEM_ADDRESS;
}
-void __init
+static int __init
vm_kmem_setup(void)
{
uint64_t size;
size = vm_kmem_offset(PMAP_MAX_KMEM_ADDRESS);
vm_object_init(&vm_kmem_kernel_object, size);
+ return 0;
}
+INIT_OP_DEFINE(vm_kmem_setup,
+ INIT_OP_DEP(pmap_bootstrap, true),
+ INIT_OP_DEP(vm_map_bootstrap, true),
+ INIT_OP_DEP(vm_object_setup, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
static int
vm_kmem_alloc_check(size_t size)
{
diff --git a/vm/vm_kmem.h b/vm/vm_kmem.h
index d845c1d8..e10c2201 100644
--- a/vm/vm_kmem.h
+++ b/vm/vm_kmem.h
@@ -20,6 +20,7 @@
#include <stdint.h>
+#include <kern/init.h>
#include <machine/pmap.h>
#include <machine/types.h>
@@ -45,11 +46,6 @@ extern char _end;
extern struct vm_map *kernel_map;
/*
- * Initialize the vm_kmem module.
- */
-void vm_kmem_setup(void);
-
-/*
* Allocate pure virtual kernel pages.
*
* The caller is reponsible for taking care of the underlying physical memory.
@@ -94,4 +90,10 @@ void * vm_kmem_map_pa(phys_addr_t pa, size_t size,
*/
void vm_kmem_unmap_pa(uintptr_t map_va, size_t map_size);
+/*
+ * This init operation provides :
+ * - kernel virtual memory allocation
+ */
+INIT_OP_DECLARE(vm_kmem_setup);
+
#endif /* _VM_VM_KMEM_H */
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 389678b6..01e0ed5d 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -728,21 +728,50 @@ static struct shell_cmd vm_map_shell_cmds[] = {
"display information about a VM map"),
};
+static int __init
+vm_map_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(vm_map_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(vm_map_setup_shell,
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(task_setup, true),
+ INIT_OP_DEP(vm_map_setup, true));
+
#endif /* X15_SHELL */
-void __init
-vm_map_setup(void)
+static int __init
+vm_map_bootstrap(void)
{
vm_map_init(kernel_map, kernel_pmap,
PMAP_MIN_KMEM_ADDRESS, PMAP_MAX_KMEM_ADDRESS);
kmem_cache_init(&vm_map_entry_cache, "vm_map_entry",
sizeof(struct vm_map_entry), 0, NULL,
KMEM_CACHE_PAGE_ONLY);
+ return 0;
+}
+
+INIT_OP_DEFINE(vm_map_bootstrap,
+ INIT_OP_DEP(kmem_bootstrap, true),
+ INIT_OP_DEP(thread_bootstrap, true));
+
+static int __init
+vm_map_setup(void)
+{
kmem_cache_init(&vm_map_cache, "vm_map", sizeof(struct vm_map),
- 0, NULL, 0);
- SHELL_REGISTER_CMDS(vm_map_shell_cmds);
+ 0, NULL, KMEM_CACHE_PAGE_ONLY);
+ return 0;
}
+INIT_OP_DEFINE(vm_map_setup,
+ INIT_OP_DEP(pmap_setup, true),
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(vm_map_bootstrap, true));
+
int
vm_map_create(struct vm_map **mapp)
{
diff --git a/vm/vm_map.h b/vm/vm_map.h
index 1e17bbb4..653eabd3 100644
--- a/vm/vm_map.h
+++ b/vm/vm_map.h
@@ -23,6 +23,7 @@
#include <stdint.h>
+#include <kern/init.h>
#include <kern/list.h>
#include <kern/mutex.h>
#include <kern/rbtree.h>
@@ -104,11 +105,6 @@ int vm_map_enter(struct vm_map *map, uintptr_t *startp,
void vm_map_remove(struct vm_map *map, uintptr_t start, uintptr_t end);
/*
- * Set up the vm_map module.
- */
-void vm_map_setup(void);
-
-/*
* Create a VM map.
*/
int vm_map_create(struct vm_map **mapp);
@@ -118,4 +114,17 @@ int vm_map_create(struct vm_map **mapp);
*/
void vm_map_info(struct vm_map *map);
+/*
+ * This init operation provides :
+ * - kernel mapping operations
+ */
+INIT_OP_DECLARE(vm_map_bootstrap);
+
+/*
+ * This init operation provides :
+ * - VM map creation
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(vm_map_setup);
+
#endif /* _VM_VM_MAP_H */
diff --git a/vm/vm_object.c b/vm/vm_object.c
index 874b26f5..649d8577 100644
--- a/vm/vm_object.c
+++ b/vm/vm_object.c
@@ -31,11 +31,17 @@
#include <vm/vm_page.h>
#include <machine/page.h>
-void __init
+static int __init
vm_object_setup(void)
{
+ return 0;
}
+INIT_OP_DEFINE(vm_object_setup,
+ INIT_OP_DEP(mutex_setup, true),
+ INIT_OP_DEP(rdxtree_setup, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
void __init
vm_object_init(struct vm_object *object, uint64_t size)
{
diff --git a/vm/vm_object.h b/vm/vm_object.h
index 046937f2..9ffe711e 100644
--- a/vm/vm_object.h
+++ b/vm/vm_object.h
@@ -26,6 +26,7 @@
#include <stdint.h>
+#include <kern/init.h>
#include <kern/rdxtree.h>
#include <vm/vm_object_types.h>
#include <vm/vm_page.h>
@@ -33,11 +34,6 @@
struct vm_object;
/*
- * Initialize the vm_object module.
- */
-void vm_object_setup(void);
-
-/*
* Initialize a VM object.
*/
void vm_object_init(struct vm_object *object, uint64_t size);
@@ -75,4 +71,10 @@ void vm_object_remove(struct vm_object *object, uint64_t start, uint64_t end);
*/
struct vm_page * vm_object_lookup(struct vm_object *object, uint64_t offset);
+/*
+ * This init operation provides :
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(vm_object_setup);
+
#endif /* _VM_OBJECT_H */
diff --git a/vm/vm_page.c b/vm/vm_page.c
index 950d04a1..7b0eb3e0 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -44,6 +44,7 @@
#include <kern/panic.h>
#include <kern/shell.h>
#include <kern/thread.h>
+#include <machine/boot.h>
#include <machine/cpu.h>
#include <machine/page.h>
#include <machine/pmem.h>
@@ -678,9 +679,21 @@ static struct shell_cmd vm_page_shell_cmds[] = {
"display information about physical memory"),
};
+static int __init
+vm_page_setup_shell(void)
+{
+ SHELL_REGISTER_CMDS(vm_page_shell_cmds);
+ return 0;
+}
+
+INIT_OP_DEFINE(vm_page_setup_shell,
+ INIT_OP_DEP(printf_setup, true),
+ INIT_OP_DEP(shell_setup, true),
+ INIT_OP_DEP(vm_page_setup, true));
+
#endif /* X15_SHELL */
-void __init
+static int __init
vm_page_setup(void)
{
struct vm_page_boot_zone *boot_zone;
@@ -741,9 +754,14 @@ vm_page_setup(void)
vm_page_is_ready = 1;
- SHELL_REGISTER_CMDS(vm_page_shell_cmds);
+ return 0;
}
+INIT_OP_DEFINE(vm_page_setup,
+ INIT_OP_DEP(boot_load_vm_page_zones, true),
+ INIT_OP_DEP(log_setup, true),
+ INIT_OP_DEP(printf_setup, true));
+
/* TODO Rename to avoid confusion with "managed pages" */
void __init
vm_page_manage(struct vm_page *page)
diff --git a/vm/vm_page.h b/vm/vm_page.h
index ea267db8..4ca34209 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -30,6 +30,7 @@
#include <stdint.h>
#include <kern/atomic.h>
+#include <kern/init.h>
#include <kern/list.h>
#include <kern/log2.h>
#include <kern/macros.h>
@@ -192,19 +193,6 @@ void vm_page_load_heap(unsigned int zone_index, phys_addr_t start,
int vm_page_ready(void);
/*
- * Set up the vm_page module.
- *
- * Architecture-specific code must have loaded zones before calling this
- * function. Zones must comply with the selector-to-zone-list table,
- * e.g. HIGHMEM is loaded if and only if DIRECTMAP, DMA32 and DMA are loaded,
- * notwithstanding zone aliasing.
- *
- * Once this function returns, the vm_page module is ready, and normal
- * allocation functions can be used.
- */
-void vm_page_setup(void);
-
-/*
* Make the given page managed by the vm_page module.
*
* If additional memory can be made usable after the VM system is initialized,
@@ -241,7 +229,7 @@ void vm_page_free(struct vm_page *page, unsigned int order);
const char * vm_page_zone_name(unsigned int zone_index);
/*
- * Display internal information about the module.
+ * Log information about physical pages.
*/
void vm_page_log_info(void);
@@ -291,4 +279,10 @@ vm_page_tryref(struct vm_page *page)
return 0;
}
+/*
+ * This init operation provides :
+ * - module fully initialized
+ */
+INIT_OP_DECLARE(vm_page_setup);
+
#endif /* _VM_VM_PAGE_H */
diff --git a/vm/vm_setup.c b/vm/vm_setup.c
deleted file mode 100644
index 9fb9c52d..00000000
--- a/vm/vm_setup.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2011-2014 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <kern/init.h>
-#include <kern/kmem.h>
-#include <kern/rdxtree.h>
-#include <kern/percpu.h>
-#include <machine/pmap.h>
-#include <vm/vm_kmem.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_setup.h>
-
-void __init
-vm_setup(void)
-{
- vm_page_setup();
- kmem_setup();
- rdxtree_setup();
- vm_object_setup();
- vm_map_setup();
- vm_kmem_setup();
- pmap_setup();
- percpu_setup();
-}
diff --git a/vm/vm_setup.h b/vm/vm_setup.h
deleted file mode 100644
index f52ddb24..00000000
--- a/vm/vm_setup.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2011 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _VM_VM_SETUP_H
-#define _VM_VM_SETUP_H
-
-/*
- * Set up the VM system.
- *
- * This function also initializes the kmem (kernel memory) allocator.
- */
-void vm_setup(void);
-
-#endif /* _VM_VM_SETUP_H */