More MMU stuff, but writing still fails

This commit is contained in:
apio 2022-11-13 15:33:53 +01:00
parent d148e0aff7
commit 4c4f72b865
3 changed files with 52 additions and 13 deletions

View File

@ -15,11 +15,11 @@ namespace MMU
CacheDisable = 16, CacheDisable = 16,
}; };
Result<void> map(u64 virt, u64 phys, Flags flags); Result<void> map(u64 virt, u64 phys, int flags);
Result<u64> unmap(u64 virt); Result<u64> unmap(u64 virt);
Result<u64> get_physical(u64 virt); Result<u64> get_physical(u64 virt);
Result<Flags> get_flags(u64 virt); Result<int> get_flags(u64 virt);
Result<void> remap(u64 virt, Flags flags); Result<void> remap(u64 virt, int flags);
void switch_page_directory(PageDirectory* dir); void switch_page_directory(PageDirectory* dir);
PageDirectory* get_page_directory(); PageDirectory* get_page_directory();

View File

@ -1,5 +1,6 @@
#include "arch/MMU.h" #include "arch/MMU.h"
#include "MemoryManager.h" #include "MemoryManager.h"
#include <String.h>
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
@ -148,7 +149,7 @@ namespace MMU
asm volatile("invlpg (%0)" : : "r"(page) : "memory"); asm volatile("invlpg (%0)" : : "r"(page) : "memory");
} }
Flags arch_flags_to_mmu(PageTableEntry& entry) int arch_flags_to_mmu(PageTableEntry& entry)
{ {
int result = Flags::None; int result = Flags::None;
if (entry.read_write) result |= Flags::ReadWrite; if (entry.read_write) result |= Flags::ReadWrite;
@ -156,10 +157,10 @@ namespace MMU
if (entry.no_execute) result |= Flags::NoExecute; if (entry.no_execute) result |= Flags::NoExecute;
if (entry.write_through) result |= Flags::WriteThrough; if (entry.write_through) result |= Flags::WriteThrough;
if (entry.cache_disabled) result |= Flags::CacheDisable; if (entry.cache_disabled) result |= Flags::CacheDisable;
return (Flags)result; return result;
} }
Result<void> map(u64 virt, u64 phys, Flags flags) Result<void> map(u64 virt, u64 phys, int flags)
{ {
auto& l4 = l4_entry(virt); auto& l4 = l4_entry(virt);
if (!l4.present) if (!l4.present)
@ -167,34 +168,43 @@ namespace MMU
auto addr = MemoryManager::alloc_physical_page(); auto addr = MemoryManager::alloc_physical_page();
if (addr.has_error()) return addr.release_error(); if (addr.has_error()) return addr.release_error();
l4.present = true; l4.present = true;
if (flags & Flags::ReadWrite) l4.read_write = true;
if (flags & Flags::User) l4.user = true;
l4.set_address(addr.release_value()); l4.set_address(addr.release_value());
memset(l3_table(virt), 0, PAGE_SIZE);
} }
if (flags & Flags::ReadWrite) l4.read_write = true;
if (flags & Flags::User) l4.user = true;
auto& l3 = l3_entry(virt); auto& l3 = l3_entry(virt);
if (!l3.present) if (!l3.present)
{ {
auto addr = MemoryManager::alloc_physical_page(); auto addr = MemoryManager::alloc_physical_page();
if (addr.has_error()) return addr.release_error(); if (addr.has_error()) return addr.release_error();
l3.present = true; l3.present = true;
if (flags & Flags::ReadWrite) l3.read_write = true;
if (flags & Flags::User) l3.user = true;
l3.set_address(addr.release_value()); l3.set_address(addr.release_value());
memset(l2_table(virt), 0, PAGE_SIZE);
} }
if (flags & Flags::ReadWrite) l3.read_write = true;
if (flags & Flags::User) l3.user = true;
if (l3.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM if (l3.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM
auto& l2 = l2_entry(virt); auto& l2 = l2_entry(virt);
if (!l2.present) if (!l2.present)
{ {
auto addr = MemoryManager::alloc_physical_page(); auto addr = MemoryManager::alloc_physical_page();
if (addr.has_error()) return addr.release_error(); if (addr.has_error()) return addr.release_error();
l2.present = true; l2.present = true;
if (flags & Flags::ReadWrite) l2.read_write = true;
if (flags & Flags::User) l2.user = true;
l2.set_address(addr.release_value()); l2.set_address(addr.release_value());
memset(l1_table(virt), 0, PAGE_SIZE);
} }
if (flags & Flags::ReadWrite) l2.read_write = true;
if (flags & Flags::User) l2.user = true;
if (l2.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM if (l2.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM
auto& l1 = l1_entry(virt); auto& l1 = l1_entry(virt);
bool was_present = l1.present; bool was_present = l1.present;
l1.present = true;
if (flags & Flags::ReadWrite) l1.read_write = true; if (flags & Flags::ReadWrite) l1.read_write = true;
if (flags & Flags::User) l1.user = true; if (flags & Flags::User) l1.user = true;
if (flags & Flags::WriteThrough) l1.write_through = true; if (flags & Flags::WriteThrough) l1.write_through = true;
@ -220,7 +230,7 @@ namespace MMU
return l1.get_address(); return l1.get_address();
} }
Result<Flags> get_flags(u64 virt) Result<int> get_flags(u64 virt)
{ {
auto& l4 = l4_entry(virt); auto& l4 = l4_entry(virt);
if (!l4.present) return err; if (!l4.present) return err;

View File

@ -1,5 +1,6 @@
#include "Framebuffer.h" #include "Framebuffer.h"
#include "Init.h" #include "Init.h"
#include "MemoryManager.h"
#include "arch/MMU.h" #include "arch/MMU.h"
#include "arch/Serial.h" #include "arch/Serial.h"
@ -16,6 +17,34 @@ extern "C" void _start()
Serial::println(MMU::get_physical((u64)fb).has_error() ? "fb is not mapped" : "fb is mapped!!"); Serial::println(MMU::get_physical((u64)fb).has_error() ? "fb is not mapped" : "fb is mapped!!");
const u64 address = 0xfffffffff8000000;
u64 physical = MemoryManager::alloc_physical_page().release_value();
bool success = !MMU::map(address, physical, MMU::ReadWrite | MMU::NoExecute).has_error();
if (success) Serial::println("Mapped page :)");
else
Serial::println("Failed to map page");
if (MMU::get_physical(address).release_value() == physical) Serial::println("Mapping is active ;)");
else
Serial::println("Mapping is not active");
int flags = MMU::get_flags(address).release_value();
if (flags & MMU::ReadWrite) Serial::println("Mapping is writable");
if (flags & MMU::NoExecute) Serial::println("Mapping is not executable");
u32* ptr = (u32*)address;
(void)*ptr;
Serial::println("Can read from pointer");
*ptr = 8;
Serial::println("Can write to pointer");
for (;;) for (;;)
; ;
} }