From 298e9130c6c57706453e401975b36461e970460b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 19 Nov 2025 00:59:51 -0500 Subject: kern/amd64: mp: Keep track of brought up cores This commit implements storing of processor descriptors per application processors as well helpers to request a CPU descriptor by index and better serialization Signed-off-by: Ian Moffett --- sys/arch/amd64/cpu/mp.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'sys/arch') diff --git a/sys/arch/amd64/cpu/mp.c b/sys/arch/amd64/cpu/mp.c index c370906..df4798d 100644 --- a/sys/arch/amd64/cpu/mp.c +++ b/sys/arch/amd64/cpu/mp.c @@ -43,6 +43,9 @@ #include #include #include +#include + +#define MAX_CPUS 256 #define dtrace(fmt, ...) trace("mp: " fmt, ##__VA_ARGS__) @@ -100,9 +103,11 @@ struct mtrr_save { uintptr_t physmask[256]; } mtrr_save; +static struct cpu_info *cpu_list[MAX_CPUS]; static struct ap_bootspace bs; static volatile size_t ap_sync = 0; -static volatile uint32_t ap_count = 0; +static uint32_t ap_count = 0; +static volatile uint32_t aps_up = 0; __section(".trampoline") static char ap_code[4096]; static void @@ -222,6 +227,8 @@ cpu_free_bootspace(struct ap_bootspace *bs) static void cpu_lm_entry(void) { + struct cpu_info *ci; + /* * Put the processor in no cache fill mode so that we can safely * update MTRRs without worrying about the ground moving under @@ -264,8 +271,18 @@ cpu_lm_entry(void) : "rax", "rbx" ); + ci = kalloc(sizeof(*ci)); + if (ci == NULL) { + panic("mp: could not allocate processor\n"); + } + + ci->id = aps_up + 1; cpu_loinit(); - atomic_inc_int(&ap_count); + cpu_conf(ci); + + atomic_inc_int(&aps_up); + cpu_list[aps_up] = ci; + for (;;) { __asmv("cli; hlt"); } @@ -338,9 +355,24 @@ cpu_lapic_cb(struct apic_header *h, size_t arg) while (!buda->is_booted); buda->is_booted = 0; + /* Don't overflow */ + if ((++ap_count) >= MAX_CPUS - 1) { + return 0; + } + return -1; /* Keep going */ } +struct cpu_info * +cpu_get(uint32_t index) +{ + if (index >= aps_up + 1) { + return NULL; + } + + return cpu_list[index]; +} + void cpu_start_aps(struct cpu_info *ci) { @@ -358,6 +390,8 @@ cpu_start_aps(struct cpu_info *ci) panic("mp: could not get current processor\n"); } + cpu_list[0] = ci; + /* Initialize the bootspace */ cpu_init_bootspace(&bs); cpu_mtrr_save(); @@ -375,9 +409,14 @@ cpu_start_aps(struct cpu_info *ci) lapic_read_id(mcb) ); - if (ap_count == 0) { + /* Wait for all processors to be up */ + while (aps_up < ap_count) { + __asmv("rep; nop"); + } + + if (aps_up == 0) { dtrace("cpu only has a single core\n"); } else { - dtrace("%d processor(s) up\n", ap_count); + dtrace("%d processor(s) up\n", aps_up); } } -- cgit v1.2.3