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 | |
parent | 85292d947faabe8828810946c7a8067ef228d6fe (diff) |
Switch to initialization operations
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); @@ -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 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 */ |