Add BSP LAPIC ID field to stivale2 SMP structure. Resolves #46
diff --git a/STIVALE2.md b/STIVALE2.md
index a5f84e3d..db4d8972 100644
--- a/STIVALE2.md
+++ b/STIVALE2.md
@@ -399,21 +399,14 @@ struct stivale2_struct_tag_smp {
// bit 0: Set if x2APIC was requested and it
// was supported and enabled.
// All other bits undefined.
+ uint32_t bsp_lapic_id; // LAPIC ID of the BSP (bootstrap processor).
+ uint32_t unused; // Reserved for future use.
uint64_t cpu_count; // Total number of logical CPUs (including BSP)
struct stivale2_smp_info smp_info[]; // Array of smp_info structs, one per
// logical processor, including BSP.
} __attribute__((packed));
```
-*Note: In the code below, the BSP refers to the bootstrap processor,*
-*AKA the processor that the system was started with, and the one whose*
-*control is handed to by stivale2 first.*
-
-*The LAPIC ID of the BSP is in most cases `0`, but this is not guaranteed.*
-*To get the LAPIC ID of the BSP, see `CPUID` leaf `1`, and in case the*
-*x2APIC is used, see `CPUID` leaves `0x1f` and `0xb`. Note that the `CPUID`*
-*instruction has to be executed on the BSP itself.*
-
```c
struct stivale2_smp_info {
uint32_t acpi_processor_uid; // ACPI Processor UID as specified by MADT
diff --git a/limine.bin b/limine.bin
index a56fc990..316186ad 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 290d6eb1..508cf611 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -322,7 +322,9 @@ void stivale2_load(char *cmdline) {
if (smp_hdr_tag != NULL) {
struct smp_information *smp_info;
size_t cpu_count;
- smp_info = init_smp(&cpu_count, bits == 64, level5pg && level5pg_requested,
+ uint32_t bsp_lapic_id;
+ smp_info = init_smp(&cpu_count, &bsp_lapic_id,
+ bits == 64, level5pg && level5pg_requested,
pagemap, smp_hdr_tag->flags & 1);
if (smp_info != NULL) {
@@ -330,6 +332,7 @@ void stivale2_load(char *cmdline) {
conv_mem_alloc(sizeof(struct stivale2_struct_tag_smp)
+ sizeof(struct smp_information) * cpu_count);
tag->tag.identifier = STIVALE2_STRUCT_TAG_SMP_ID;
+ tag->bsp_lapic_id = bsp_lapic_id;
tag->cpu_count = cpu_count;
tag->flags |= (smp_hdr_tag->flags & 1) && x2apic_check();
diff --git a/stage2/sys/smp.c b/stage2/sys/smp.c
index f2f4a53e..9e9dc539 100644
--- a/stage2/sys/smp.c
+++ b/stage2/sys/smp.c
@@ -96,6 +96,7 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
}
struct smp_information *init_smp(size_t *cpu_count,
+ uint32_t *_bsp_lapic_id,
bool longmode,
bool lv5,
pagemap_t pagemap,
@@ -130,6 +131,10 @@ struct smp_information *init_smp(size_t *cpu_count,
return NULL;
bsp_x2apic_id = edx;
+
+ *_bsp_lapic_id = bsp_x2apic_id;
+ } else {
+ *_bsp_lapic_id = bsp_lapic_id;
}
*cpu_count = 0;
diff --git a/stage2/sys/smp.h b/stage2/sys/smp.h
index 4e79c58d..ec4741c7 100644
--- a/stage2/sys/smp.h
+++ b/stage2/sys/smp.h
@@ -15,6 +15,7 @@ struct smp_information {
} __attribute__((packed));
struct smp_information *init_smp(size_t *cpu_count,
+ uint32_t *_bsp_lapic_id,
bool longmode,
bool lv5,
pagemap_t pagemap,
diff --git a/stivale/stivale2.h b/stivale/stivale2.h
index 569e8d13..03decded 100644
--- a/stivale/stivale2.h
+++ b/stivale/stivale2.h
@@ -142,6 +142,8 @@ struct stivale2_smp_info {
struct stivale2_struct_tag_smp {
struct stivale2_tag tag;
uint64_t flags;
+ uint32_t bsp_lapic_id;
+ uint32_t unused;
uint64_t cpu_count;
struct stivale2_smp_info smp_info[];
} __attribute__((packed));
diff --git a/test/stivale2.c b/test/stivale2.c
index ef0989b0..789d320f 100644
--- a/test/stivale2.c
+++ b/test/stivale2.c
@@ -61,7 +61,7 @@ void stivale2_main(struct stivale2_struct *info) {
}
case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: {
struct stivale2_struct_tag_framebuffer *f = (struct stivale2_struct_tag_framebuffer *)tag;
- e9_puts("Framebuffer tag:");
+ e9_puts("Framebuffer tag:");
e9_printf("\tAddress: %x", f->framebuffer_addr);
e9_printf("\tWidth: %d", f->framebuffer_width);
e9_printf("\tHeight: %d", f->framebuffer_height);
@@ -100,8 +100,9 @@ void stivale2_main(struct stivale2_struct *info) {
case STIVALE2_STRUCT_TAG_SMP_ID: {
struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag;
e9_puts("SMP tag:");
- e9_printf("\tFlags: %x", s->flags);
- e9_printf("\tCPU Count: %d", s->cpu_count);
+ e9_printf("\tFlags: %x", s->flags);
+ e9_printf("\tBSP LAPIC ID: %d", s->bsp_lapic_id);
+ e9_printf("\tCPU Count: %d", s->cpu_count);
for (size_t i = 0; i < s->cpu_count; i++) {
struct stivale2_smp_info in = s->smp_info[i];
e9_printf("\t\tProcessor ID: %d", in.processor_id);
