:: commit a688a1dd4f3434f8c26f4262bed94f799190d592

mintsuki <mintsuki@protonmail.com> — 2022-03-28 06:00

parents: b4fd10afd4

limine: Add stack size feature

diff --git a/PROTOCOL.md b/PROTOCOL.md
index 4aaef08d..2de5d0c3 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -141,7 +141,8 @@ Legacy PIC and IO APIC IRQs are all masked.
 If booted by EFI/UEFI, boot services are exited.
 
 `rsp` is set to point to a stack, in bootloader-reserved memory, which is
-at least 16KiB (16384 bytes) in size. An invalid return address of 0 is pushed
+at least 16KiB (16384 bytes) in size, or the size specified in the Stack
+Size Request (see below). An invalid return address of 0 is pushed
 to the stack before jumping to the kernel.
 
 All other general purpose registers are set to 0.
@@ -182,6 +183,32 @@ struct limine_bootloader_info_response {
 `name` and `version` are 0-terminated ASCII strings containing the name and
 version of the loading bootloader.
 
+### Stack Size Feature
+
+ID:
+```c
+#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
+```
+
+Request:
+```c
+struct limine_stack_size_request {
+    uint64_t id[4];
+    uint64_t revision;
+    struct limine_stack_size_response *response;
+    uint64_t stack_size;
+};
+```
+
+* `stack_size` - The requested stack size (also used for SMP processors).
+
+Response:
+```c
+struct limine_stack_size_response {
+    uint64_t revision;
+};
+```
+
 ### HHDM (Higher Half Direct Map) Feature
 
 ID:
@@ -384,7 +411,7 @@ struct limine_smp_info {
 * `processor_id` - ACPI Processor UID as specified by the MADT
 * `lapic_id` - Local APIC ID of the processor as specified by the MADT
 * `goto_address` - An atomic write to this field causes the parked CPU to
-jump to the written address, on a 16KiB stack. A pointer to the
+jump to the written address, on a 16KiB (or Stack Size Request size) stack. A pointer to the
 `struct limine_smp_info` structure of the CPU is passed in `RDI`. Other than
 that, the CPU state will be the same as described for the bootstrap
 processor. This field is unused for the structure describing the bootstrap
diff --git a/common/protos/limine.c b/common/protos/limine.c
index cac3240d..174ac1a0 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -348,6 +348,22 @@ FEAT_START
 FEAT_END
 #endif
 
+    // Stack size
+    uint64_t stack_size = 16384;
+FEAT_START
+    struct limine_stack_size_request *stack_size_request = get_request(LIMINE_STACK_SIZE_REQUEST);
+    if (stack_size_request == NULL) {
+        break; // next feature
+    }
+
+    struct limine_stack_size_response *stack_size_response =
+        ext_mem_alloc(sizeof(struct limine_stack_size_response));
+
+    stack_size = stack_size_request->stack_size;
+
+    stack_size_request->response = reported_addr(stack_size_response);
+FEAT_END
+
     // Kernel file
 FEAT_START
     struct limine_kernel_file_request *kernel_file_request = get_request(LIMINE_KERNEL_FILE_REQUEST);
@@ -553,7 +569,7 @@ FEAT_END
     local_gdt->ptr_hi = local_gdt_base >> 32;
 #endif
 
-    void *stack = ext_mem_alloc(16384) + 16384;
+    void *stack = ext_mem_alloc(stack_size) + stack_size;
 
     pagemap_t pagemap = {0};
     pagemap = stivale_build_pagemap(want_5lv, true, ranges, ranges_count, true,
@@ -585,8 +601,8 @@ FEAT_START
     }
 
     for (size_t i = 0; i < cpu_count; i++) {
-        void *cpu_stack = ext_mem_alloc(16384) + 16384;
-        smp_info[i].stack_addr = reported_addr(cpu_stack + 16384);
+        void *cpu_stack = ext_mem_alloc(stack_size) + stack_size;
+        smp_info[i].stack_addr = reported_addr(cpu_stack + stack_size);
     }
 
     struct limine_smp_response *smp_response =
diff --git a/limine.h b/limine.h
index 44a1958f..b68a842e 100644
--- a/limine.h
+++ b/limine.h
@@ -52,6 +52,21 @@ struct limine_bootloader_info_request {
     LIMINE_PTR(struct limine_bootloader_info_response *) response;
 };
 
+/* Stack size */
+
+#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
+
+struct limine_stack_size_response {
+    uint64_t revision;
+};
+
+struct limine_stack_size_request {
+    uint64_t id[4];
+    uint64_t revision;
+    LIMINE_PTR(struct limine_stack_size_response *) response;
+    uint64_t stack_size;
+};
+
 /* HHDM */
 
 #define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
tab: 248 wrap: offon