summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-07-07 16:29:24 +0200
committerRichard Braun <rbraun@sceen.net>2018-07-07 16:29:24 +0200
commit29c42a7d4f82f9d8f4af5ed96e56274851977978 (patch)
tree2a5b9635e2f8593bf4016f93ecb61e5da47f6fcf /arch
parentbf1ee95728d81204b0cb30aa8d59d67c6c699138 (diff)
x86/cpu: use atomic operations for CPU boot synchronization
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/machine/cpu.c12
-rw-r--r--arch/x86/machine/cpu_i.h9
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];