From dc40c2f6adf53e7ad8411d98bc7129665570e496 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Wed, 5 Sep 2018 22:26:23 -0700 Subject: [PATCH] Changes from the reorg branch Add CR4 options: global pages, FXSAVE, PCIDs Better page manager page-in flags Remove obsolete rflags-saving in create_process --- src/kernel/memory_bootstrap.cpp | 8 ++++++++ src/kernel/page_manager.cpp | 11 +++++++---- src/kernel/scheduler.cpp | 4 ---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/kernel/memory_bootstrap.cpp b/src/kernel/memory_bootstrap.cpp index 097ba8d..071789a 100644 --- a/src/kernel/memory_bootstrap.cpp +++ b/src/kernel/memory_bootstrap.cpp @@ -429,6 +429,14 @@ memory_initialize(const void *memory_map, size_t map_length, size_t desc_length) __asm__ __volatile__ ( "mov %%cr3, %0" : "=r" (cr3) ); page_table *tables = reinterpret_cast(cr3 & ~0xfffull); + // We'll need to make sure the options we want in CR4 are set + uint64_t cr4; + __asm__ __volatile__ ( "mov %%cr4, %0" : "=r" (cr4) ); + cr4 |= 0x00080; // Enable global pages + cr4 |= 0x00200; // Enable FXSAVE/FXRSTOR + cr4 |= 0x20000; // Enable PCIDs + __asm__ __volatile__ ( "mov %0, %%cr4" :: "r" (cr4) ); + // Now go through EFi's memory map and find a region of scratch space. const unsigned want_pages = 32; uint64_t free_region_start_phys = diff --git a/src/kernel/page_manager.cpp b/src/kernel/page_manager.cpp index 968cc30..e66273f 100644 --- a/src/kernel/page_manager.cpp +++ b/src/kernel/page_manager.cpp @@ -379,8 +379,7 @@ void * page_manager::map_pages(addr_t address, size_t count, bool user, page_table *pml4) { void *ret = reinterpret_cast(address); - if (pml4 == nullptr) - pml4 = get_pml4(); + if (!pml4) pml4 = get_pml4(); while (count) { kassert(m_free, "page_manager::map_pages ran out of free pages!"); @@ -537,6 +536,10 @@ page_manager::page_in(page_table *pml4, addr_t phys_addr, addr_t virt_addr, size page_table_indices idx{virt_addr}; page_table *tables[4] = {pml4, nullptr, nullptr, nullptr}; + uint64_t flags = user ? + 0x00f: // writethru, user, write, present + 0x10b; // global, writethru, write, present + for (; idx[0] < 512; idx[0] += 1) { check_needs_page(tables[0], idx[0], user); tables[1] = tables[0]->get(idx[0]); @@ -550,7 +553,7 @@ page_manager::page_in(page_table *pml4, addr_t phys_addr, addr_t virt_addr, size count >= 512 && tables[2]->get(idx[2]) == nullptr) { // Do a 2MiB page instead - tables[2]->entries[idx[2]] = phys_addr | (user ? 0x8f : 0x8b); + tables[2]->entries[idx[2]] = phys_addr | flags | 0x80; phys_addr += page_size * 512; count -= 512; if (count == 0) return; @@ -561,7 +564,7 @@ page_manager::page_in(page_table *pml4, addr_t phys_addr, addr_t virt_addr, size tables[3] = tables[2]->get(idx[2]); for (; idx[3] < 512; idx[3] += 1) { - tables[3]->entries[idx[3]] = phys_addr | (user ? 0xf : 0xb); + tables[3]->entries[idx[3]] = phys_addr | flags; phys_addr += page_size; if (--count == 0) return; } diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index 25a681c..33f78cf 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -19,7 +19,6 @@ extern "C" { void taskA(); void taskAend(); void ramdisk_process_loader(); - void load_process(void *copy_start, size_t butes, cpu_state state); }; @@ -55,9 +54,6 @@ load_process(void *copy_start, size_t bytes, cpu_state state) static process create_process(uint16_t pid) { - uint64_t flags; - __asm__ __volatile__ ( "pushf; pop %0" : "=r" (flags) ); - uint16_t kcs = (1 << 3) | 0; // Kernel CS is GDT entry 1, ring 0 uint16_t cs = (5 << 3) | 3; // User CS is GDT entry 5, ring 3