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
This commit is contained in:
Justin C. Miller
2018-09-05 22:26:23 -07:00
parent 2fb92e8592
commit dc40c2f6ad
3 changed files with 15 additions and 8 deletions

View File

@@ -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) ); __asm__ __volatile__ ( "mov %%cr3, %0" : "=r" (cr3) );
page_table *tables = reinterpret_cast<page_table *>(cr3 & ~0xfffull); page_table *tables = reinterpret_cast<page_table *>(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. // Now go through EFi's memory map and find a region of scratch space.
const unsigned want_pages = 32; const unsigned want_pages = 32;
uint64_t free_region_start_phys = uint64_t free_region_start_phys =

View File

@@ -379,8 +379,7 @@ void *
page_manager::map_pages(addr_t address, size_t count, bool user, page_table *pml4) page_manager::map_pages(addr_t address, size_t count, bool user, page_table *pml4)
{ {
void *ret = reinterpret_cast<void *>(address); void *ret = reinterpret_cast<void *>(address);
if (pml4 == nullptr) if (!pml4) pml4 = get_pml4();
pml4 = get_pml4();
while (count) { while (count) {
kassert(m_free, "page_manager::map_pages ran out of free pages!"); 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_indices idx{virt_addr};
page_table *tables[4] = {pml4, nullptr, nullptr, nullptr}; 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) { for (; idx[0] < 512; idx[0] += 1) {
check_needs_page(tables[0], idx[0], user); check_needs_page(tables[0], idx[0], user);
tables[1] = tables[0]->get(idx[0]); 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 && count >= 512 &&
tables[2]->get(idx[2]) == nullptr) { tables[2]->get(idx[2]) == nullptr) {
// Do a 2MiB page instead // 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; phys_addr += page_size * 512;
count -= 512; count -= 512;
if (count == 0) return; 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]); tables[3] = tables[2]->get(idx[2]);
for (; idx[3] < 512; idx[3] += 1) { 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; phys_addr += page_size;
if (--count == 0) return; if (--count == 0) return;
} }

View File

@@ -19,7 +19,6 @@ extern "C" {
void taskA(); void taskA();
void taskAend(); void taskAend();
void ramdisk_process_loader(); void ramdisk_process_loader();
void load_process(void *copy_start, size_t butes, cpu_state state); 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 static process
create_process(uint16_t pid) 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 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 uint16_t cs = (5 << 3) | 3; // User CS is GDT entry 5, ring 3