:: commit 73fa01d1d034618f02d2d921a154e202b88955f2

mintsuki <mintsuki@protonmail.com> — 2020-09-18 18:21

parents: 927851e24d

smp: Fix bug where started APs would not be aware of 5-level paging

diff --git a/limine.bin b/limine.bin
index 12871eac..36f13670 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 695fc727..329dd8b7 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -327,8 +327,8 @@ void stivale2_load(char *cmdline, int boot_drive) {
     if (smp_hdr_tag != NULL) {
         struct stivale2_struct_tag_smp *tag = balloc(sizeof(struct stivale2_struct_tag_smp));
 
-        init_smp((size_t*)&tag->cpu_count, bits == 64, pagemap,
-                 smp_hdr_tag->flags & 1);
+        init_smp((size_t*)&tag->cpu_count, bits == 64, level5pg && level5pg_requested,
+                 pagemap, smp_hdr_tag->flags & 1);
 
         append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
     }
diff --git a/stage2/sys/smp.c b/stage2/sys/smp.c
index bfb1f789..72eaa8b9 100644
--- a/stage2/sys/smp.c
+++ b/stage2/sys/smp.c
@@ -47,12 +47,12 @@ uint8_t  smp_tpl_target_mode;
 
 static bool smp_start_ap(uint8_t lapic_id, struct gdtr *gdtr,
                          struct smp_information *info_struct,
-                         uint8_t target_mode, uint32_t pagemap) {
+                         bool longmode, bool lv5, uint32_t pagemap) {
     // Prepare the trampoline
     smp_tpl_info_struct = info_struct;
     smp_tpl_booted_flag = 0;
     smp_tpl_pagemap     = pagemap;
-    smp_tpl_target_mode = target_mode;
+    smp_tpl_target_mode = ((uint32_t)lv5 << 1) | (uint32_t)longmode;
     smp_tpl_gdt         = *gdtr;
 
     // Send the INIT IPI
@@ -76,6 +76,7 @@ static bool smp_start_ap(uint8_t lapic_id, struct gdtr *gdtr,
 
 struct smp_information *init_smp(size_t   *cpu_count,
                                  bool      longmode,
+                                 bool      lv5,
                                  pagemap_t pagemap,
                                  bool      x2apic) {
     // Search for MADT table
@@ -120,12 +121,14 @@ struct smp_information *init_smp(size_t   *cpu_count,
 
                 // Try to start the AP
                 if (!smp_start_ap(lapic->lapic_id, &gdtr, info_struct,
-                                  longmode ? 1 : 0, (uint32_t)pagemap.top_level)) {
+                                  longmode, lv5, (uint32_t)pagemap.top_level)) {
                     print("smp: FAILED to bring-up AP\n");
                     brewind(sizeof(struct smp_information));
                     continue;
                 }
 
+                print("smp: Successfully brought up AP\n");
+
                 (*cpu_count)++;
                 break;
             }
diff --git a/stage2/sys/smp.h b/stage2/sys/smp.h
index 28a87b09..fa207f72 100644
--- a/stage2/sys/smp.h
+++ b/stage2/sys/smp.h
@@ -15,6 +15,7 @@ struct smp_information {
 
 struct smp_information *init_smp(size_t   *cpu_count,
                                  bool      longmode,
+                                 bool      lv5,
                                  pagemap_t pagemap,
                                  bool      x2apic);
 
diff --git a/stage2/sys/smp_trampoline.asm b/stage2/sys/smp_trampoline.asm
index fc467fd2..a78c3b32 100644
--- a/stage2/sys/smp_trampoline.asm
+++ b/stage2/sys/smp_trampoline.asm
@@ -36,16 +36,24 @@ smp_trampoline:
     btr eax, 30
     mov cr0, eax
 
-    cmp dword [smp_tpl_target_mode], 0
-    je parking32
-
-    mov eax, dword [smp_tpl_pagemap]
-    mov cr3, eax
+    test dword [smp_tpl_target_mode], (1 << 0)
+    jz parking32
 
     mov eax, cr4
     bts eax, 5
     mov cr4, eax
 
+    test dword [smp_tpl_target_mode], (1 << 1)
+    jz .no5lv
+
+    mov eax, cr4
+    bts eax, 12
+    mov cr4, eax
+
+  .no5lv:
+    mov eax, dword [smp_tpl_pagemap]
+    mov cr3, eax
+
     mov ecx, 0xc0000080
     rdmsr
     bts eax, 8
tab: 248 wrap: offon