Mapping finally works!!

This commit is contained in:
apio 2022-11-13 16:31:32 +01:00
parent 4c4f72b865
commit d6c56fb512
2 changed files with 27 additions and 13 deletions

View File

@ -1,5 +1,6 @@
#include "arch/MMU.h"
#include "MemoryManager.h"
#include "arch/Serial.h"
#include <String.h>
#define PAGE_SIZE 4096
@ -23,21 +24,21 @@ struct [[gnu::packed]] PageTableEntry
u8 available2 : 3;
bool no_execute : 1;
void set_address(uint64_t addr);
uint64_t get_address();
void set_address(u64 addr);
u64 get_address();
};
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wconversion"
void PageTableEntry::set_address(uint64_t addr)
void PageTableEntry::set_address(u64 addr)
{
this->address = (addr >> 12);
}
uint64_t PageTableEntry::get_address()
u64 PageTableEntry::get_address()
{
return (uint64_t)this->address << 12;
return (u64)this->address << 12;
}
#pragma GCC pop_options
@ -170,6 +171,7 @@ namespace MMU
l4.present = true;
l4.set_address(addr.release_value());
memset(l3_table(virt), 0, PAGE_SIZE);
l4.ignore0 = l4.ignore1 = 0;
}
if (flags & Flags::ReadWrite) l4.read_write = true;
if (flags & Flags::User) l4.user = true;
@ -182,6 +184,7 @@ namespace MMU
l3.present = true;
l3.set_address(addr.release_value());
memset(l2_table(virt), 0, PAGE_SIZE);
l3.ignore0 = l3.ignore1 = 0;
}
if (flags & Flags::ReadWrite) l3.read_write = true;
if (flags & Flags::User) l3.user = true;
@ -196,6 +199,7 @@ namespace MMU
l2.present = true;
l2.set_address(addr.release_value());
memset(l1_table(virt), 0, PAGE_SIZE);
l2.ignore0 = l2.ignore1 = 0;
}
if (flags & Flags::ReadWrite) l2.read_write = true;
if (flags & Flags::User) l2.user = true;
@ -203,15 +207,16 @@ namespace MMU
if (l2.larger_pages) return err; // FIXME: Replacing larger pages is not supported ATM
auto& l1 = l1_entry(virt);
bool was_present = l1.present;
if (l1.present) return err; // Please explicitly unmap the page before mapping it again.
l1.ignore0 = l1.ignore1 = false;
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;
if (flags & Flags::CacheDisable) l1.cache_disabled = true;
if (flags & Flags::NoExecute) l1.no_execute = true;
if (l1.ignore0 || l1.ignore1) return {1};
l1.set_address(phys);
if (was_present) flush_page(virt);
return {};
}

View File

@ -21,30 +21,39 @@ extern "C" void _start()
u64 physical = MemoryManager::alloc_physical_page().release_value();
bool success = !MMU::map(address, physical, MMU::ReadWrite | MMU::NoExecute).has_error();
auto rc = MMU::map(address, physical, MMU::ReadWrite);
bool success = !rc.has_error();
int flags;
u8* ptr;
if (success) Serial::println("Mapped page :)");
else
{
Serial::println("Failed to map page");
goto failure;
}
if (MMU::get_physical(address).release_value() == physical) Serial::println("Mapping is active ;)");
else
{
Serial::println("Mapping is not active");
goto failure;
}
int flags = MMU::get_flags(address).release_value();
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 = (u8*)address;
*ptr = 8;
Serial::println("Can write to pointer");
failure:
for (;;)
;
}