:: commit 6c7e096800d06bbc801a8dead4b729268c14d9b0

mintsuki <mintsuki@protonmail.com> — 2021-03-14 05:13

parents: 3674ce3af9

stivale2: Implement EDID and EFI system table tags

diff --git a/stage23/Makefile b/stage23/Makefile
index 1bdf09f8..6406fdbc 100644
--- a/stage23/Makefile
+++ b/stage23/Makefile
@@ -23,7 +23,7 @@ COM_OUTPUT = false
 E9_OUTPUT = false
 
 BUILD_ID := $(shell dd if=/dev/urandom count=8 bs=1 | od -An -t x8 | sed 's/^ /0x/')
-LIMINE_VERSION := $(shell git describe --exact-match --tags `git log -n1 --pretty='%h'` || git log -n1 --pretty='%h')
+LIMINE_VERSION := $(shell git describe --exact-match --tags `git log -n1 --pretty='%h'` || git log -n1 --pretty='%h' && echo -n "(trunk)")
 WERROR = -Werror
 CFLAGS = -O3 -g -pipe -Wall -Wextra $(WERROR)
 S2CFLAGS = -Os -g -pipe -Wall -Wextra $(WERROR)
diff --git a/stage23/drivers/edid.c b/stage23/drivers/edid.c
index bd437bf0..62fd23c8 100644
--- a/stage23/drivers/edid.c
+++ b/stage23/drivers/edid.c
@@ -25,12 +25,17 @@ struct edid_info_struct *get_edid_info(void) {
     if ((r.eax & 0xff00) != 0)
         goto fail;
 
-    print("edid: Success.\n");
-    return buf;
+    for (size_t i = 0; i < sizeof(struct edid_info_struct); i++)
+        if (((uint8_t *)buf)[i] != 0)
+            goto success;
 
 fail:
     print("edid: Could not fetch EDID data.\n");
     return NULL;
+
+success:
+    print("edid: Success.\n");
+    return buf;
 }
 
 #endif
@@ -76,12 +81,17 @@ struct edid_info_struct *get_edid_info(void) {
 
     memcpy(buf, edid->Edid, sizeof(struct edid_info_struct));
 
-    print("edid: Success.\n");
-    return buf;
+    for (size_t i = 0; i < sizeof(struct edid_info_struct); i++)
+        if (((uint8_t *)buf)[i] != 0)
+            goto success;
 
 fail:
     print("edid: Could not fetch EDID data.\n");
     return NULL;
+
+success:
+    print("edid: Success.\n");
+    return buf;
 }
 
 #endif
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index 13d8df42..6e1f5622 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -45,7 +45,7 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
 
     term_vbe(colourscheme, 64, 0, NULL);
 
-    print("Limine " LIMINE_VERSION "\n\n", print);
+    print("Limine " LIMINE_VERSION "\n\n");
 
     disk_create_index();
 
@@ -101,7 +101,13 @@ void stage3_common(void) {
     if (!strcmp(proto, "stivale")) {
         stivale_load(config, cmdline);
     } else if (!strcmp(proto, "stivale2")) {
-        stivale2_load(config, cmdline, boot_volume->pxe);
+#if defined (bios)
+        void *efi_system_table = NULL;
+#elif defined (uefi)
+        void *efi_system_table = gST;
+#endif
+
+        stivale2_load(config, cmdline, boot_volume->pxe, efi_system_table);
     } else if (!strcmp(proto, "linux")) {
 #if defined (bios)
         linux_load(config, cmdline);
diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c
index c4c1bf51..cc99c552 100644
--- a/stage23/protos/stivale2.c
+++ b/stage23/protos/stivale2.c
@@ -24,6 +24,7 @@
 #include <mm/mtrr.h>
 #include <stivale/stivale2.h>
 #include <pxe/tftp.h>
+#include <drivers/edid.h>
 
 #define KASLR_SLIDE_BITMASK 0x000FFF000u
 
@@ -51,7 +52,7 @@ static void append_tag(struct stivale2_struct *s, struct stivale2_tag *tag) {
     s->tags   = (uint64_t)(size_t)tag;
 }
 
-void stivale2_load(char *config, char *cmdline, bool pxe) {
+void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table) {
     struct file_handle *kernel = ext_mem_alloc(sizeof(struct file_handle));
 
     char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
@@ -294,6 +295,38 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
     }
     }
 
+    //////////////////////////////////////////////
+    // Create EDID struct tag
+    //////////////////////////////////////////////
+    {
+    struct edid_info_struct *edid_info = get_edid_info();
+
+    if (edid_info != NULL) {
+        struct stivale2_struct_tag_edid *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_edid) + sizeof(struct edid_info_struct));
+        tag->tag.identifier = STIVALE2_STRUCT_TAG_EDID_ID;
+
+        tag->edid_size = sizeof(struct edid_info_struct);
+
+        memcpy(tag->edid_information, edid_info, sizeof(struct edid_info_struct));
+
+        append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
+    }
+    }
+
+    //////////////////////////////////////////////
+    // Create EFI system table struct tag
+    //////////////////////////////////////////////
+    {
+    if (efi_system_table != NULL) {
+        struct stivale2_struct_tag_efi_system_table *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_efi_system_table));
+        tag->tag.identifier = STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID;
+
+        tag->system_table = (uint64_t)(uintptr_t)efi_system_table;
+
+        append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
+    }
+    }
+
     // Check if 5-level paging tag is requesting support
     bool level5pg_requested = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_5LV_PAGING_ID) ? true : false;
 
diff --git a/stage23/protos/stivale2.h b/stage23/protos/stivale2.h
index 8d076822..61fcb25e 100644
--- a/stage23/protos/stivale2.h
+++ b/stage23/protos/stivale2.h
@@ -1,6 +1,8 @@
 #ifndef __PROTOS__STIVALE2_H__
 #define __PROTOS__STIVALE2_H__
 
-void stivale2_load(char *config, char *cmdline, bool pxe);
+#include <stdbool.h>
+
+void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table);
 
 #endif
diff --git a/test/stivale2.c b/test/stivale2.c
index 6932227b..7e80ed65 100644
--- a/test/stivale2.c
+++ b/test/stivale2.c
@@ -38,9 +38,12 @@ struct stivale2_header header2 = {
     .tags        = (uint64_t)&framebuffer_request
 };
 
+static volatile int cpu_up = 0;
+
 static void ap_entry(struct stivale2_smp_info *s) {
-    e9_printf("AP %u started", s->lapic_id);
-    for (;;);
+    e9_printf("\t\t\tAP %d started", s->lapic_id);
+    cpu_up = 1;
+    for (;;) asm("hlt");
 }
 
 void stivale2_main(struct stivale2_struct *info) {
@@ -87,6 +90,12 @@ void stivale2_main(struct stivale2_struct *info) {
                 e9_printf("\tBlue mask size:  %d", f->blue_mask_shift);
                 break;
             }
+            case STIVALE2_STRUCT_TAG_EDID_ID: {
+                struct stivale2_struct_tag_edid *edid = (struct stivale2_struct_tag_edid *)tag;
+
+                e9_printf("EDID information at %x:", edid->edid_information);
+                e9_printf("\tSize: %d", edid->edid_size);
+            }
             case STIVALE2_STRUCT_TAG_FB_MTRR_ID: {
                 e9_puts("Framebuffer WC MTRR tag:");
                 e9_puts("\tFramebuffer WC MTRR enabled");
@@ -120,6 +129,11 @@ void stivale2_main(struct stivale2_struct *info) {
                 e9_printf("\tFlags: %x", f->flags);
                 break;
             }
+            case STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID: {
+                struct stivale2_struct_tag_efi_system_table *t = (struct stivale2_struct_tag_efi_system_table *)tag;
+                e9_printf("EFI system table at: %x", t->system_table);
+                break;
+            }
             case STIVALE2_STRUCT_TAG_SMP_ID: {
                 struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag;
                 e9_puts("SMP tag:");
@@ -135,7 +149,9 @@ void stivale2_main(struct stivale2_struct *info) {
                     e9_printf("\t\tExtra Argument: %x", in->extra_argument);
                     if (in->lapic_id != s->bsp_lapic_id) {
                         in->target_stack = (uintptr_t)stacks[in->lapic_id] + sizeof(stack);
-                        in->goto_address = ap_entry;
+                        in->goto_address = (uintptr_t)ap_entry;
+                        while (cpu_up == 0);
+                        cpu_up = 0;
                     }
                 }
                 break;
@@ -148,5 +164,5 @@ void stivale2_main(struct stivale2_struct *info) {
     }
 
     // Enter our sublime pale slumber.
-    for (;;);
+    for (;;) asm("hlt");
 }
tab: 248 wrap: offon