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
