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) {
