:: commit a01e5ecd1a2da778ac951026844561cc7b00211d

mintsuki <mintsuki@protonmail.com> — 2021-05-04 21:00

parents: 4bd3a540a8

stivale2: Implement higher half returned addresses flag

diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c
index 0e606c2c..335e7f72 100644
--- a/stage23/protos/stivale.c
+++ b/stage23/protos/stivale.c
@@ -110,7 +110,6 @@ void stivale_load(char *config, char *cmdline) {
     }
 
     bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
-    pagemap_t pagemap = stivale_build_pagemap(want_5lv, false);
 
     if (stivale_hdr.entry_point != 0)
         entry_point = stivale_hdr.entry_point;
@@ -224,6 +223,10 @@ void stivale_load(char *config, char *cmdline) {
     efi_exit_boot_services();
 #endif
 
+    pagemap_t pagemap = {0};
+    if (bits == 64)
+        pagemap = stivale_build_pagemap(want_5lv, false);
+
     // Reserve 32K at 0x70000
     memmap_alloc_range(0x70000, 0x8000, MEMMAP_USABLE, true, true, false, false);
 
diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c
index c859fe9d..ad347fc2 100644
--- a/stage23/protos/stivale2.c
+++ b/stage23/protos/stivale2.c
@@ -26,6 +26,10 @@
 #include <drivers/edid.h>
 #include <drivers/vga_textmode.h>
 
+#define REPORTED_ADDR(PTR) \
+    ((PTR) + ((stivale2_hdr.flags & (1 << 1)) ? \
+    (want_5lv ? 0xff00000000000000 : 0xffff800000000000) : 0))
+
 struct stivale2_struct stivale2_struct = {0};
 
 inline static size_t get_phys_addr(uint64_t addr) {
@@ -127,6 +131,8 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
             panic("stivale2: Section .stivale2hdr is smaller than size of the struct.");
     }
 
+    bool want_5lv = (get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_5LV_PAGING_ID) ? true : false) && level5pg;
+
     if (stivale2_hdr.entry_point != 0)
         entry_point = stivale2_hdr.entry_point;
 
@@ -145,7 +151,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
     struct stivale2_struct_tag_kernel_file *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_kernel_file));
     tag->tag.identifier = STIVALE2_STRUCT_TAG_KERNEL_FILE_ID;
 
-    tag->kernel_file = (uint64_t)(uintptr_t)kernel;
+    tag->kernel_file = REPORTED_ADDR((uint64_t)(uintptr_t)kernel);
 
     append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
     }
@@ -216,7 +222,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
         if (!uri_open(&f, module_path))
             panic("Requested module with path \"%s\" not found!", module_path);
 
-        m->begin = (uint64_t)(size_t)freadall(&f, STIVALE2_MMAP_KERNEL_AND_MODULES);
+        m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(&f, STIVALE2_MMAP_KERNEL_AND_MODULES));
         m->end   = m->begin + f.size;
 
         print("stivale2: Requested module %u:\n", i);
@@ -236,7 +242,9 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
     struct stivale2_struct_tag_rsdp *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_rsdp));
     tag->tag.identifier = STIVALE2_STRUCT_TAG_RSDP_ID;
 
-    tag->rsdp = (uint64_t)(size_t)acpi_get_rsdp();
+    uint64_t rsdp = (uint64_t)(size_t)acpi_get_rsdp();
+    if (rsdp)
+        tag->rsdp = REPORTED_ADDR(rsdp);
 
     append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
     }
@@ -248,8 +256,13 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
     struct stivale2_struct_tag_smbios *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_smbios));
     tag->tag.identifier = STIVALE2_STRUCT_TAG_SMBIOS_ID;
 
-    acpi_get_smbios((void **)&tag->smbios_entry_32,
-                    (void **)&tag->smbios_entry_64);
+    uint64_t smbios_entry_32 = 0, smbios_entry_64 = 0;
+    acpi_get_smbios((void **)&smbios_entry_32, (void **)&smbios_entry_64);
+
+    if (smbios_entry_32)
+        tag->smbios_entry_32 = REPORTED_ADDR(smbios_entry_32);
+    if (smbios_entry_64)
+        tag->smbios_entry_64 = REPORTED_ADDR(smbios_entry_64);
 
     append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
     }
@@ -261,7 +274,7 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
     struct stivale2_struct_tag_cmdline *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_cmdline));
     tag->tag.identifier = STIVALE2_STRUCT_TAG_CMDLINE_ID;
 
-    tag->cmdline = (uint64_t)(size_t)cmdline;
+    tag->cmdline = REPORTED_ADDR((uint64_t)(size_t)cmdline);
 
     append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
     }
@@ -346,7 +359,7 @@ skip_modeset:;
                                MEMMAP_FRAMEBUFFER, false, false, false, true);
 
             tag->memory_model       = STIVALE2_FBUF_MMODEL_RGB;
-            tag->framebuffer_addr   = fb->framebuffer_addr;
+            tag->framebuffer_addr   = REPORTED_ADDR(fb->framebuffer_addr);
             tag->framebuffer_width  = fb->framebuffer_width;
             tag->framebuffer_height = fb->framebuffer_height;
             tag->framebuffer_bpp    = fb->framebuffer_bpp;
@@ -410,19 +423,17 @@ skip_modeset:;
         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;
+        tag->system_table = REPORTED_ADDR((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;
     bool unmap_null = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_UNMAP_NULL_ID) ? true : false;
 
     pagemap_t pagemap = {0};
     if (bits == 64)
-        pagemap = stivale_build_pagemap(level5pg && level5pg_requested, unmap_null);
+        pagemap = stivale_build_pagemap(want_5lv, unmap_null);
 
 #if defined (uefi)
     efi_exit_boot_services();
@@ -440,7 +451,7 @@ skip_modeset:;
         uint32_t bsp_lapic_id;
         smp_info = init_smp(sizeof(struct stivale2_struct_tag_smp), (void **)&tag,
                             &cpu_count, &bsp_lapic_id,
-                            bits == 64, level5pg && level5pg_requested,
+                            bits == 64, want_5lv,
                             pagemap, smp_hdr_tag->flags & 1);
 
         if (smp_info != NULL) {
@@ -480,10 +491,10 @@ skip_modeset:;
     //////////////////////////////////////////////
     // List tags
     //////////////////////////////////////////////
-    print("Generated tags:\n");
+    print("stivale2: Generated tags:\n");
     struct stivale2_tag *taglist = (void*)(size_t)stivale2_struct.tags;
     for (size_t i = 0; ; i++) {
-        print("Tag #%u  ID: %X\n", i, taglist->identifier);
+        print("          Tag #%u  ID: %X\n", i, taglist->identifier);
         if (taglist->next)
             taglist = (void*)(size_t)taglist->next;
         else
@@ -493,6 +504,6 @@ skip_modeset:;
     // Clear terminal for kernels that will use the stivale2 terminal
     term_write("\e[2J\e[H", 7);
 
-    stivale_spinup(bits, level5pg && level5pg_requested, &pagemap,
-                   entry_point, (uint64_t)(uintptr_t)&stivale2_struct, stivale2_hdr.stack);
+    stivale_spinup(bits, want_5lv, &pagemap, entry_point,
+                   (uint64_t)(uintptr_t)&stivale2_struct, stivale2_hdr.stack);
 }
diff --git a/test/stivale2.c b/test/stivale2.c
index f95dde45..5a9bf46a 100644
--- a/test/stivale2.c
+++ b/test/stivale2.c
@@ -42,7 +42,7 @@ __attribute__((section(".stivale2hdr"), used))
 struct stivale2_header header2 = {
     .entry_point = (uint64_t)stivale2_main,
     .stack       = (uintptr_t)stacks[0] + sizeof(stack),
-    .flags       = 0,
+    .flags       = 1 << 1,
     .tags        = (uint64_t)&framebuffer_request
 };
 
tab: 248 wrap: offon