More MMU stuff, but writing still fails
This commit is contained in:
parent
d148e0aff7
commit
4c4f72b865
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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 (;;)
|
||||||
;
|
;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user