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 (;;);
}
