diff --git a/kernel/arch/x86_64/PageTable.cpp b/kernel/arch/x86_64/PageTable.cpp index b468a80b..5d728cc5 100644 --- a/kernel/arch/x86_64/PageTable.cpp +++ b/kernel/arch/x86_64/PageTable.cpp @@ -20,7 +20,6 @@ namespace Kernel RecursiveSpinLock PageTable::s_fast_page_lock; static PageTable* s_kernel = nullptr; - static PageTable* s_current = nullptr; static bool s_has_nxe = false; static bool s_has_pge = false; @@ -71,40 +70,51 @@ namespace Kernel void PageTable::initialize() { if (CPUID::has_nxe()) - { - asm volatile( - "movl $0xC0000080, %ecx;" - "rdmsr;" - "orl $0x800, %eax;" - "wrmsr" - ); s_has_nxe = true; - } - uint32_t ecx, edx; - CPUID::get_features(ecx, edx); - if (edx & CPUID::EDX_PGE) - { - asm volatile( - "movq %cr4, %rax;" - "orq $0x80, %rax;" - "movq %rax, %cr4;" - ); + if (CPUID::has_pge()) s_has_pge = true; - } - - // enable write protect to kernel - asm volatile( - "movq %cr0, %rax;" - "orq $0x10000, %rax;" - "movq %rax, %cr0;" - ); ASSERT(s_kernel == nullptr); s_kernel = new PageTable(); ASSERT(s_kernel); + s_kernel->initialize_kernel(); - s_kernel->load(); + s_kernel->initial_load(); + } + + void PageTable::initial_load() + { + if (s_has_nxe) + { + asm volatile( + "movl $0xC0000080, %%ecx;" + "rdmsr;" + "orl $0x800, %%eax;" + "wrmsr" + ::: "eax", "ecx", "edx", "memory" + ); + } + + if (s_has_pge) + { + asm volatile( + "movq %%cr4, %%rax;" + "orq $0x80, %%rax;" + "movq %%rax, %%cr4;" + ::: "rax" + ); + } + + // enable write protect + asm volatile( + "movq %%cr0, %%rax;" + "orq $0x10000, %%rax;" + "movq %%rax, %%cr0;" + ::: "rax" + ); + + load(); } PageTable& PageTable::kernel() @@ -113,12 +123,6 @@ namespace Kernel return *s_kernel; } - PageTable& PageTable::current() - { - ASSERT(s_current); - return *s_current; - } - bool PageTable::is_valid_pointer(uintptr_t pointer) { if (!is_canonical(pointer)) @@ -308,7 +312,7 @@ namespace Kernel { SpinLockGuard _(m_lock); asm volatile("movq %0, %%cr3" :: "r"(m_highest_paging_struct)); - s_current = this; + Processor::current().m_current_page_table = this; } void PageTable::invalidate(vaddr_t vaddr) @@ -367,8 +371,6 @@ namespace Kernel { ASSERT(vaddr); ASSERT(vaddr != fast_page()); - if (vaddr >= KERNEL_OFFSET && s_current) - ASSERT(vaddr >= (vaddr_t)g_kernel_start); if ((vaddr >= KERNEL_OFFSET) != (this == s_kernel)) Kernel::panic("mapping {8H} to {8H}, kernel: {}", paddr, vaddr, this == s_kernel); diff --git a/kernel/include/kernel/CPUID.h b/kernel/include/kernel/CPUID.h index 4daea7aa..0983e7b8 100644 --- a/kernel/include/kernel/CPUID.h +++ b/kernel/include/kernel/CPUID.h @@ -78,5 +78,6 @@ namespace CPUID void get_features(uint32_t& ecx, uint32_t& edx); bool is_64_bit(); bool has_nxe(); + bool has_pge(); } diff --git a/kernel/include/kernel/Memory/PageTable.h b/kernel/include/kernel/Memory/PageTable.h index e6d7dc65..0855b80e 100644 --- a/kernel/include/kernel/Memory/PageTable.h +++ b/kernel/include/kernel/Memory/PageTable.h @@ -40,7 +40,7 @@ namespace Kernel static void initialize(); static PageTable& kernel(); - static PageTable& current(); + static PageTable& current() { return *reinterpret_cast(Processor::current().m_current_page_table); } static constexpr vaddr_t fast_page() { return KERNEL_OFFSET; } @@ -109,6 +109,7 @@ namespace Kernel vaddr_t reserve_free_contiguous_pages(size_t page_count, vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX); void load(); + void initial_load(); InterruptState lock() const { return m_lock.lock(); } void unlock(InterruptState state) const { m_lock.unlock(state); } diff --git a/kernel/include/kernel/Processor.h b/kernel/include/kernel/Processor.h index f0e363e8..3adf5be3 100644 --- a/kernel/include/kernel/Processor.h +++ b/kernel/include/kernel/Processor.h @@ -87,7 +87,10 @@ namespace Kernel GDT* m_gdt { nullptr }; IDT* m_idt { nullptr }; + void* m_current_page_table { nullptr }; + friend class BAN::Vector; + friend class PageTable; }; #else #error diff --git a/kernel/kernel/CPUID.cpp b/kernel/kernel/CPUID.cpp index 08c040e3..99f12fe4 100644 --- a/kernel/kernel/CPUID.cpp +++ b/kernel/kernel/CPUID.cpp @@ -50,6 +50,13 @@ namespace CPUID return buffer[3] & (1 << 20); } + bool has_pge() + { + uint32_t ecx, edx; + get_features(ecx, edx); + return edx & CPUID::EDX_PGE; + } + const char* feature_string_ecx(uint32_t feat) { switch (feat) diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 5f5cae3a..b3713173 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -107,6 +107,7 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info) dprintln("BSP initialized"); PageTable::initialize(); + PageTable::kernel().initial_load(); dprintln("PageTable initialized"); Heap::initialize(); @@ -211,8 +212,10 @@ extern "C" void ap_main() using namespace Kernel; Processor::current().initialize(); + PageTable::kernel().initial_load(); + dprintln("ap{} initialized", Processor::current_id()); for (;;) - asm volatile(""); + asm volatile("hlt"); }