:: commit 776e46cf4454b54eb06a9438e1b9bebe9b040cf4

mintsuki <mintsuki@protonmail.com> — 2024-07-18 00:44

parents: 37f1bcb44b

protos/limine: Add firmware type features

diff --git a/PROTOCOL.md b/PROTOCOL.md
index 60b34e0d..f7cb4c26 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -396,6 +396,37 @@ struct limine_bootloader_info_response {
 `name` and `version` are 0-terminated ASCII strings containing the name and
 version of the loading bootloader.
 
+### Firmware Type Feature
+
+ID:
+```c
+#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 }
+```
+
+Request:
+```c
+struct limine_firmware_type_request {
+    uint64_t id[4];
+    uint64_t revision;
+    struct limine_firmware_type_response *response;
+};
+```
+
+Response:
+```c
+struct limine_firmware_type_response {
+    uint64_t revision;
+    uint64_t firmware_type;
+};
+```
+
+`firmware_type` is an enumeration that can have one of the following values:
+```c
+#define LIMINE_FIRMWARE_TYPE_X86BIOS 0
+#define LIMINE_FIRMWARE_TYPE_UEFI32 1
+#define LIMINE_FIRMWARE_TYPE_UEFI64 2
+```
+
 ### Stack Size Feature
 
 ID:
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 53a11ce3..2dc3ffc7 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -594,6 +594,31 @@ FEAT_START
     bootloader_info_request->response = reported_addr(bootloader_info_response);
 FEAT_END
 
+    // Firmware type feature
+FEAT_START
+    struct limine_firmware_type_request *firmware_type_request = get_request(LIMINE_FIRMWARE_TYPE_REQUEST);
+    if (firmware_type_request == NULL) {
+        break; // next feature
+    }
+
+    struct limine_firmware_type_response *firmware_type_response =
+        ext_mem_alloc(sizeof(struct limine_firmware_type_response));
+
+    firmware_type_response->firmware_type =
+#if defined (UEFI)
+#if defined (__i386__)
+        LIMINE_FIRMWARE_TYPE_UEFI32
+#else
+        LIMINE_FIRMWARE_TYPE_UEFI64
+#endif
+#else
+        LIMINE_FIRMWARE_TYPE_X86BIOS
+#endif
+    ;
+
+    firmware_type_request->response = reported_addr(firmware_type_response);
+FEAT_END
+
     // Kernel address feature
 FEAT_START
     struct limine_kernel_address_request *kernel_address_request = get_request(LIMINE_KERNEL_ADDRESS_REQUEST);
diff --git a/limine.h b/limine.h
index 2e6bc337..7d93730c 100644
--- a/limine.h
+++ b/limine.h
@@ -103,6 +103,25 @@ struct limine_bootloader_info_request {
     LIMINE_PTR(struct limine_bootloader_info_response *) response;
 };
 
+/* Firmware type */
+
+#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 }
+
+#define LIMINE_FIRMWARE_TYPE_X86BIOS 0
+#define LIMINE_FIRMWARE_TYPE_UEFI32 1
+#define LIMINE_FIRMWARE_TYPE_UEFI64 2
+
+struct limine_firmware_type_response {
+    uint64_t revision;
+    uint64_t firmware_type;
+};
+
+struct limine_firmware_type_request {
+    uint64_t id[4];
+    uint64_t revision;
+    LIMINE_PTR(struct limine_firmware_type_response *) response;
+};
+
 /* Stack size */
 
 #define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
diff --git a/test/limine.c b/test/limine.c
index 7806d3b9..22d48b4e 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -34,6 +34,12 @@ static volatile struct limine_bootloader_info_request bootloader_info_request =
     .revision = 0, .response = NULL
 };
 
+__attribute__((section(".limine_requests")))
+static volatile struct limine_firmware_type_request firmware_type_request = {
+    .id = LIMINE_FIRMWARE_TYPE_REQUEST,
+    .revision = 0, .response = NULL
+};
+
 __attribute__((section(".limine_requests")))
 static volatile struct limine_hhdm_request hhdm_request = {
     .id = LIMINE_HHDM_REQUEST,
@@ -166,6 +172,19 @@ static char *get_memmap_type(uint64_t type) {
     }
 }
 
+static char *firmware_type_str(uint64_t t) {
+    switch (t) {
+        case LIMINE_FIRMWARE_TYPE_X86BIOS:
+            return "x86 BIOS";
+        case LIMINE_FIRMWARE_TYPE_UEFI32:
+            return "32-bit UEFI";
+        case LIMINE_FIRMWARE_TYPE_UEFI64:
+            return "64-bit UEFI";
+        default:
+            return "???";
+    }
+}
+
 static void print_file(struct limine_file *file) {
     e9_printf("File->Revision: %d", file->revision);
     e9_printf("File->Address: %x", file->address);
@@ -266,6 +285,17 @@ FEAT_START
     e9_printf("Bootloader version: %s", bootloader_info_response->version);
 FEAT_END
 
+FEAT_START
+    e9_printf("");
+    if (firmware_type_request.response == NULL) {
+        e9_printf("Firmware type not passed");
+        break;
+    }
+    struct limine_firmware_type_response *firmware_type_response = firmware_type_request.response;
+    e9_printf("Firmware type feature, revision %d", firmware_type_response->revision);
+    e9_printf("Firmware type: %s", firmware_type_str(firmware_type_response->firmware_type));
+FEAT_END
+
 FEAT_START
     e9_printf("");
     if (kernel_address_request.response == NULL) {
tab: 248 wrap: offon