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 }
