From 3f5b29c3c9a7d5ffda8bd88abb0a89c10761e877 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 18 Mar 2022 01:17:56 +0100 Subject: [PATCH] limine: Add SMP request --- common/limine.h | 29 +++++++++++++++++++++++++++++ common/protos/limine.c | 36 ++++++++++++++++++++++++++++++++++++ test/limine.c | 22 ++++++++++++++++++++++ 3 files changed, 87 insertions(+) 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 (;;); }