:: commit 3f5b29c3c9a7d5ffda8bd88abb0a89c10761e877

mintsuki <mintsuki@protonmail.com> — 2022-03-18 00:17

parents: fb54571b34

limine: Add SMP request

diff --git a/common/limine.h b/common/limine.h
index 37114129..c9a1faf5 100644
--- a/common/limine.h
+++ b/common/limine.h
@@ -96,6 +96,35 @@ struct limine_5_level_paging_request {
     LIMINE_PTR(struct limine_5_level_paging_response *) response;
 };
 
+// SMP
+
+#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
+
+#define LIMINE_SMP_X2APIC (1 << 0)
+
+struct limine_smp_info {
+    uint32_t processor_id;
+    uint32_t lapic_id;
+    uint64_t reserved;
+    LIMINE_PTR(void *) goto_address;
+    uint64_t extra_argument;
+};
+
+struct limine_smp_response {
+    uint64_t flags;
+
+    uint32_t bsp_lapic_id;
+    uint32_t unused;
+    uint64_t cpus_count;
+    LIMINE_PTR(struct limine_smp_info *) cpus;
+};
+
+struct limine_smp_request {
+    uint64_t id[4];
+    uint64_t flags;
+    LIMINE_PTR(struct limine_smp_response *) response;
+};
+
 // Memory map
 
 #define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
diff --git a/common/protos/limine.c b/common/protos/limine.c
index ddaf1f68..bbbc730b 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -427,6 +427,42 @@ FEAT_END
     efi_exit_boot_services();
 #endif
 
+    // SMP
+FEAT_START
+    struct limine_smp_request *smp_request = get_request(LIMINE_SMP_REQUEST);
+    if (smp_request == NULL) {
+        break; // next feature
+    }
+
+    struct limine_smp_info *smp_array;
+    struct smp_information *smp_info;
+    size_t cpu_count;
+    uint32_t bsp_lapic_id;
+    smp_info = init_smp(0, (void **)&smp_array,
+                        &cpu_count, &bsp_lapic_id,
+                        true, want_5lv,
+                        pagemap, smp_request->flags & LIMINE_SMP_X2APIC, true);
+
+    if (smp_info == NULL) {
+        break;
+    }
+
+    for (size_t i = 0; i < cpu_count; i++) {
+        void *cpu_stack = ext_mem_alloc(8192) + 8192;
+        smp_info[i].stack_addr = reported_addr(cpu_stack + 8192);
+    }
+
+    struct limine_smp_response *smp_response =
+        ext_mem_alloc(sizeof(struct limine_smp_response));
+
+    smp_response->flags |= (smp_request->flags & LIMINE_SMP_X2APIC) && x2apic_check();
+    smp_response->bsp_lapic_id = bsp_lapic_id;
+    smp_response->cpus_count = cpu_count;
+    smp_response->cpus = reported_addr(smp_array);
+
+    smp_request->response = reported_addr(smp_response);
+FEAT_END
+
     // Memmap
 FEAT_START
     struct limine_memmap_request *memmap_request = get_request(LIMINE_MEMMAP_REQUEST);
diff --git a/test/limine.c b/test/limine.c
index ede5619e..006a8f09 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -42,6 +42,11 @@ struct limine_smbios_request smbios_request = {
     .flags = 0, .response = NULL
 };
 
+struct limine_smp_request _smp_request = {
+    .id = LIMINE_SMP_REQUEST,
+    .flags = 0, .response = NULL
+};
+
 static char *get_memmap_type(uint64_t type) {
     switch (type) {
         case LIMINE_MEMMAP_USABLE:
@@ -189,5 +194,22 @@ FEAT_START
     e9_printf("SMBIOS 64-bit entry at: %x", smbios_response->entry_64);
 FEAT_END
 
+FEAT_START
+    if (_smp_request.response == NULL) {
+        e9_printf("SMP info not passed");
+        break;
+    }
+    struct limine_smp_response *smp_response = _smp_request.response;
+    e9_printf("");
+    e9_printf("Flags: %x", smp_response->flags);
+    e9_printf("BSP LAPIC ID: %x", smp_response->bsp_lapic_id);
+    e9_printf("CPUs count: %d", smp_response->cpus_count);
+    for (size_t i = 0; i < smp_response->cpus_count; i++) {
+        struct limine_smp_info *cpu = &smp_response->cpus[i];
+        e9_printf("Processor ID: %x", cpu->processor_id);
+        e9_printf("LAPIC ID: %x", cpu->lapic_id);
+    }
+FEAT_END
+
     for (;;);
 }
tab: 248 wrap: offon