:: commit b7f4412948fd96497548e3f1668b02cdee0869b9

mintsuki <mintsuki@protonmail.com> — 2020-10-25 03:58

parents: 7867d23e45

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);
tab: 248 wrap: offon