summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/cpu/mp.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-11-19 00:59:51 -0500
committerIan Moffett <ian@osmora.org>2025-11-19 00:59:51 -0500
commit298e9130c6c57706453e401975b36461e970460b (patch)
tree79479d922e7e1e45c734b235dc78e5d51232d657 /sys/arch/amd64/cpu/mp.c
parentd38730fc2cdb21382eb9f96e70b0078435122d7d (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>
Diffstat (limited to 'sys/arch/amd64/cpu/mp.c')
-rw-r--r--sys/arch/amd64/cpu/mp.c47
1 files changed, 43 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);
}
}