More MMU stuff, but writing still fails
This commit is contained in:
parent
d148e0aff7
commit
4c4f72b865
@ -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();
|
||||
|
@ -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;
|
||||
if (flags & Flags::ReadWrite) l4.read_write = true;
|
||||
if (flags & Flags::User) l4.user = 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;
|
||||
|
||||
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;
|
||||
if (flags & Flags::ReadWrite) l3.read_write = true;
|
||||
if (flags & Flags::User) l3.user = 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;
|
||||
|
||||
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;
|
||||
if (flags & Flags::ReadWrite) l2.read_write = true;
|
||||
if (flags & Flags::User) l2.user = 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;
|
||||
|
||||
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;
|
||||
|
@ -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 (;;)
|
||||
;
|
||||
}
|
Loading…
Reference in New Issue
Block a user