:: commit 0b55faa97ffb0634c93f3d839054042e667eb1b3

sanana <umutinanerdogan@pm.me> — 2025-06-30 19:07

parents: 65237a14c8

protos/limine: Add bootloader performance feature

This feature provides the same information as the new Boot Loader Interface
variables, but encoded in a nicer way for Limine protocol executables.
diff --git a/PROTOCOL.md b/PROTOCOL.md
index daadb9e8..d8ccc964 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -1381,3 +1381,43 @@ given by bootloader tags, and as such the `/chosen` node properties should be ig
 
 Note: If the DTB contained `memory@...` nodes, they will get removed.
 Executables may not rely on these nodes and should use the Memory Map feature instead.
+
+### Bootloader Performance Feature
+
+ID:
+```c
+#define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST { LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17 }
+```
+
+Request:
+```c
+struct limine_bootloader_performance_request {
+    uint64_t id[4];
+    uint64_t revision;
+    struct limine_bootloader_performance_response *response;
+};
+```
+
+Response:
+```c
+struct limine_bootloader_performance_response {
+    uint64_t revision;
+    uint64_t reset_usec;
+    uint64_t init_usec;
+    uint64_t exec_usec;
+};
+```
+
+* `reset_usec` - time of system reset in microseconds relative to an arbitrary point in the past.
+* `init_usec` - time of bootloader initialisation in microseconds relative to an arbitrary point in
+the past.
+* `exec_usec` - time of executable handoff in microseconds relative to an arbitrary point in the
+past.
+
+Note: Data provided by this feature is purely informational. The ACPI Firmware Performance Data
+Table may have more correct data and should be preferred if it exists. Bootloaders may implement
+this feature using the FPDT.
+
+Note: The bootloader may assume `reset_usec` is zero if it cannot or does not know the time of
+system reset, due to implementation or platform restrictions. `reset_usec` will usually be 0 or a
+value near zero, but may be any value relative to any point in the past.
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 99942d98..cd88f557 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -1395,6 +1395,27 @@ FEAT_END
     }
 #endif
 
+    // Bootloader Performance
+    // rdtsc_usec depends on EFI boot services
+FEAT_START
+    if (usec_at_bootloader_entry == 0) {
+        break;
+    }
+
+    struct limine_bootloader_performance_request *perf_request = get_request(LIMINE_BOOTLOADER_PERFORMANCE_REQUEST);
+    if (perf_request == NULL) {
+        break;
+    }
+
+    struct limine_bootloader_performance_response *perf_response =
+        ext_mem_alloc(sizeof(struct limine_bootloader_performance_response));
+
+    perf_response->reset_usec = 0;
+    perf_response->init_usec = usec_at_bootloader_entry;
+    perf_response->exec_usec = rdtsc_usec();
+    perf_request->response = reported_addr(perf_response);
+FEAT_END
+
 #if defined (UEFI)
     efi_exit_boot_services();
 #endif
diff --git a/limine.h b/limine.h
index d1d20089..e27d1b18 100644
--- a/limine.h
+++ b/limine.h
@@ -747,6 +747,23 @@ struct limine_riscv_bsp_hartid_request {
     LIMINE_PTR(struct limine_riscv_bsp_hartid_response *) response;
 };
 
+/* Bootloader Performance */
+
+#define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST { LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17 }
+
+struct limine_bootloader_performance_response {
+    uint64_t revision;
+    uint64_t reset_usec;
+    uint64_t init_usec;
+    uint64_t exec_usec;
+};
+
+struct limine_bootloader_performance_request {
+    uint64_t id[4];
+    uint64_t revision;
+    LIMINE_PTR(struct limine_bootloader_performance_response *) response;
+};
+
 #ifdef __cplusplus
 }
 #endif
tab: 248 wrap: offon