summaryrefslogtreecommitdiff
path: root/arch/x86/machine
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/machine')
-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
24 files changed, 430 insertions, 213 deletions
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 */