sys/smp: Synchronise AP MTRRs with the BSP
diff --git a/common/GNUmakefile b/common/GNUmakefile
index 924333e0..76994705 100644
--- a/common/GNUmakefile
+++ b/common/GNUmakefile
@@ -69,6 +69,8 @@ ifeq ($(TARGET),bios)
override CPPFLAGS_FOR_TARGET := \
$(CPPFLAGS_FOR_TARGET) \
-DBIOS
+ override NASM_TARGET := \
+ -DIA32_TARGET
endif
ifeq ($(TARGET),uefi-x86-64)
@@ -87,6 +89,8 @@ ifeq ($(TARGET),uefi-x86-64)
-I'$(call SHESCAPE,$(BUILDDIR))/limine-efi/inc/x86_64' \
$(CPPFLAGS_FOR_TARGET) \
-DUEFI
+ override NASM_TARGET := \
+ -DX86_64_TARGET
endif
ifeq ($(TARGET),uefi-ia32)
@@ -101,6 +105,8 @@ ifeq ($(TARGET),uefi-ia32)
-I'$(call SHESCAPE,$(BUILDDIR))/limine-efi/inc/ia32' \
$(CPPFLAGS_FOR_TARGET) \
-DUEFI
+ override NASM_TARGET := \
+ -DIA32_TARGET
endif
ifeq ($(TARGET),uefi-aarch64)
@@ -566,29 +572,29 @@ endif
ifeq ($(TARGET),bios)
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_ia32
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_bios_ia32
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_x86
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
endif
ifeq ($(TARGET),uefi-x86-64)
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_x86_64
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf64 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf64 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_uefi_x86_64
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf64 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf64 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_x86
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf64 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf64 -o '$(call SHESCAPE,$@)'
endif
ifeq ($(TARGET),uefi-aarch64)
@@ -614,13 +620,13 @@ endif
ifeq ($(TARGET),uefi-ia32)
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_ia32
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_uefi_ia32
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
$(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_x86
$(MKDIR_P) "$$(dirname '$(call SHESCAPE,$@)')"
- nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) -f elf32 -o '$(call SHESCAPE,$@)'
+ nasm '$(call SHESCAPE,$<)' -F dwarf -g -Wall $(WERROR_FLAG) $(NASM_TARGET) -f elf32 -o '$(call SHESCAPE,$@)'
endif
diff --git a/common/sys/smp.c b/common/sys/smp.c
index 2467e598..bb0ceb4b 100644
--- a/common/sys/smp.c
+++ b/common/sys/smp.c
@@ -11,6 +11,7 @@
#include <sys/gdt.h>
#include <mm/vmm.h>
#include <mm/pmm.h>
+#include <mm/mtrr.h>
#define LIMINE_NO_POINTERS
#include <limine.h>
#if defined (__riscv64)
@@ -29,6 +30,8 @@ struct trampoline_passed_info {
uint32_t smp_tpl_info_struct;
struct gdtr smp_tpl_gdt;
uint64_t smp_tpl_hhdm;
+ uint64_t smp_tpl_mtrr_restore;
+ uint64_t smp_tpl_temp_stack;
} __attribute__((packed));
static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
@@ -43,6 +46,11 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
memcpy(trampoline, smp_trampoline_start, smp_trampoline_size);
}
+ static void *temp_stack = NULL;
+ if (temp_stack == NULL) {
+ temp_stack = ext_mem_alloc(8192);
+ }
+
static struct trampoline_passed_info *passed_info = NULL;
if (passed_info == NULL) {
passed_info = (void *)(((uintptr_t)trampoline + smp_trampoline_size)
@@ -58,6 +66,8 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
| ((uint32_t)wp << 4);
passed_info->smp_tpl_gdt = *gdtr;
passed_info->smp_tpl_hhdm = hhdm;
+ passed_info->smp_tpl_mtrr_restore = (uint64_t)(uintptr_t)mtrr_restore;
+ passed_info->smp_tpl_temp_stack = (uint64_t)(uintptr_t)temp_stack;
asm volatile ("" ::: "memory");
@@ -171,6 +181,8 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
*cpu_count = 0;
// Try to start all APs
+ mtrr_save();
+
for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin;
(uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length;
madt_ptr += *(madt_ptr + 1)) {
diff --git a/common/sys/smp_trampoline.asm_x86 b/common/sys/smp_trampoline.asm_x86
index 29b13a0f..0300b323 100644
--- a/common/sys/smp_trampoline.asm_x86
+++ b/common/sys/smp_trampoline.asm_x86
@@ -54,7 +54,7 @@ smp_trampoline_start:
wrmsr
.nox2apic:
- lea esp, [ebx + (temp_stack.top - smp_trampoline_start)]
+ mov esp, [ebx + (passed_info.temp_stack - smp_trampoline_start)]
mov eax, cr4
bts eax, 5
@@ -80,6 +80,11 @@ smp_trampoline_start:
bts eax, 31
mov cr0, eax
+%ifdef IA32_TARGET
+ ; Synchronise MTRRs with BSP
+ call [ebx + (passed_info.mtrr_restore - smp_trampoline_start)]
+%endif
+
lea eax, [ebx + (.mode64 - smp_trampoline_start)]
push 0x28
push eax
@@ -123,8 +128,15 @@ smp_trampoline_start:
bits 64
parking64:
mov ebx, ebx
+
+%ifdef X86_64_TARGET
+ ; Synchronise MTRRs with BSP
+ call [rbx + (passed_info.mtrr_restore - smp_trampoline_start)]
+%endif
+
mov edi, dword [rbx + (passed_info.smp_info_struct - smp_trampoline_start)]
add rdi, qword [rbx + (passed_info.hhdm - smp_trampoline_start)]
+
mov eax, 1
lock xchg dword [rbx + (passed_info.booted_flag - smp_trampoline_start)], eax
@@ -160,11 +172,6 @@ parking64:
xor r15, r15
ret
-align 16
-temp_stack:
- times 128 db 0
- .top:
-
invalid_idt:
times 2 dq 0
@@ -179,6 +186,10 @@ passed_info:
dq 0
.hhdm:
dq 0
+ .mtrr_restore:
+ dq 0
+ .temp_stack:
+ dq 0
smp_trampoline_end:
