diff options
| author | Ian Moffett <ian@osmora.org> | 2025-11-19 00:59:51 -0500 |
|---|---|---|
| committer | Ian Moffett <ian@osmora.org> | 2025-11-19 00:59:51 -0500 |
| commit | 298e9130c6c57706453e401975b36461e970460b (patch) | |
| tree | 79479d922e7e1e45c734b235dc78e5d51232d657 | |
| parent | d38730fc2cdb21382eb9f96e70b0078435122d7d (diff) | |
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 <ian@osmora.org>
| -rw-r--r-- | sys/arch/amd64/cpu/mp.c | 47 | ||||
| -rw-r--r-- | sys/inc/mu/cpu.h | 5 |
2 files changed, 48 insertions, 4 deletions
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 <mu/cpu.h> #include <vm/vm.h> #include <vm/phys.h> +#include <vm/kalloc.h> + +#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); } } diff --git a/sys/inc/mu/cpu.h b/sys/inc/mu/cpu.h index 7974cf1..05637f5 100644 --- a/sys/inc/mu/cpu.h +++ b/sys/inc/mu/cpu.h @@ -51,6 +51,11 @@ struct cpu_info { struct cpu_info *cpu_self(void); /* + * Get a processor by index + */ +struct cpu_info *cpu_get(uint32_t index); + +/* * Configure a processor core */ void cpu_conf(struct cpu_info *ci); |
