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,
};
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> get_physical(u64 virt);
Result<Flags> get_flags(u64 virt);
Result<void> remap(u64 virt, Flags flags);
Result<int> get_flags(u64 virt);
Result<void> remap(u64 virt, int flags);
void switch_page_directory(PageDirectory* dir);
PageDirectory* get_page_directory();

View File

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

View File

@ -1,5 +1,6 @@
#include "Framebuffer.h"
#include "Init.h"
#include "MemoryManager.h"
#include "arch/MMU.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!!");
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 (;;)
;
}