diff options
author | Richard Braun <rbraun@sceen.net> | 2018-07-07 16:29:24 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2018-07-07 16:29:24 +0200 |
commit | 29c42a7d4f82f9d8f4af5ed96e56274851977978 (patch) | |
tree | 2a5b9635e2f8593bf4016f93ecb61e5da47f6fcf /arch | |
parent | bf1ee95728d81204b0cb30aa8d59d67c6c699138 (diff) |
x86/cpu: use atomic operations for CPU boot synchronization
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/machine/cpu.c | 12 | ||||
-rw-r--r-- | arch/x86/machine/cpu_i.h | 9 |
2 files changed, 10 insertions, 11 deletions
diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c index f2acd77d..e8cdb19d 100644 --- a/arch/x86/machine/cpu.c +++ b/arch/x86/machine/cpu.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <string.h> +#include <kern/atomic.h> #include <kern/init.h> #include <kern/kmem.h> #include <kern/log.h> @@ -1076,7 +1077,7 @@ cpu_build(struct cpu *cpu) cpu->virt_addr_width = ((unsigned short)eax >> 8) & 0xff; } - cpu->state = CPU_STATE_ON; + atomic_store(&cpu->started, 1, ATOMIC_RELEASE); } static void __init @@ -1247,6 +1248,7 @@ void __init cpu_mp_setup(void) { uint16_t reset_vector[2]; + unsigned int started; struct cpu *cpu; void *ptr; @@ -1294,8 +1296,12 @@ cpu_mp_setup(void) lapic_ipi_startup(cpu->apic_id, BOOT_MP_TRAMPOLINE_ADDR >> 12); cpu_delay(200); - while (cpu->state == CPU_STATE_OFF) { - cpu_pause(); + for (;;) { + started = atomic_load(&cpu->started, ATOMIC_ACQUIRE); + + if (started) { + break; + } } } } diff --git a/arch/x86/machine/cpu_i.h b/arch/x86/machine/cpu_i.h index f877fce3..66fe5f51 100644 --- a/arch/x86/machine/cpu_i.h +++ b/arch/x86/machine/cpu_i.h @@ -108,13 +108,6 @@ struct cpu_gdt { #define CPU_VENDOR_ID_SIZE 13 #define CPU_MODEL_NAME_SIZE 49 -/* - * CPU states. - * TODO Boolean. - */ -#define CPU_STATE_OFF 0 -#define CPU_STATE_ON 1 - struct cpu { unsigned int id; unsigned int apic_id; @@ -157,7 +150,7 @@ struct cpu { struct cpu_tss df_tss; #endif /* __LP64__ */ - volatile int state; // TODO Atomic accessors + unsigned int started; alignas(CPU_DATA_ALIGN) char intr_stack[CPU_INTR_STACK_SIZE]; alignas(CPU_DATA_ALIGN) char df_stack[CPU_INTR_STACK_SIZE]; |