mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:48:12 +00:00

The kernel is now no longer identity mapped to the bottom 8MiB of memory, and is now mapped at the higher address of `0xc0000000`. The lower ~1MiB of memory (from GRUB's mmap), however is still identity mapped to provide an easy way for the kernel to get physical pages for things such as DMA etc. These could later be mapped to the higher address too, as I'm not too sure how to go about doing this elegantly without a lot of address subtractions.
59 lines
1.8 KiB
C++
59 lines
1.8 KiB
C++
#include <Kernel/Process.h>
|
|
#include <Kernel/Thread.h>
|
|
#include <Kernel/VM/MemoryManager.h>
|
|
#include <Kernel/VM/PageDirectory.h>
|
|
|
|
static const u32 userspace_range_base = 0x01000000;
|
|
static const u32 kernelspace_range_base = 0xc0000000;
|
|
|
|
static HashMap<u32, PageDirectory*>& pdb_map()
|
|
{
|
|
ASSERT_INTERRUPTS_DISABLED();
|
|
static HashMap<u32, PageDirectory*>* map;
|
|
if (!map)
|
|
map = new HashMap<u32, PageDirectory*>;
|
|
return *map;
|
|
}
|
|
|
|
RefPtr<PageDirectory> PageDirectory::find_by_pdb(u32 pdb)
|
|
{
|
|
InterruptDisabler disabler;
|
|
return pdb_map().get(pdb).value_or({});
|
|
}
|
|
|
|
PageDirectory::PageDirectory(PhysicalAddress paddr)
|
|
: m_range_allocator(VirtualAddress(kernelspace_range_base + 0x800000), 0x3f000000)
|
|
{
|
|
m_directory_page = PhysicalPage::create(paddr, true, false);
|
|
InterruptDisabler disabler;
|
|
pdb_map().set(m_directory_page->paddr().get(), this);
|
|
}
|
|
|
|
PageDirectory::PageDirectory(Process& process, const RangeAllocator* parent_range_allocator)
|
|
: m_process(&process)
|
|
, m_range_allocator(parent_range_allocator ? RangeAllocator(*parent_range_allocator) : RangeAllocator(VirtualAddress(userspace_range_base), kernelspace_range_base - userspace_range_base))
|
|
{
|
|
MM.populate_page_directory(*this);
|
|
InterruptDisabler disabler;
|
|
pdb_map().set(m_directory_page->paddr().get(), this);
|
|
}
|
|
|
|
PageDirectory::~PageDirectory()
|
|
{
|
|
#ifdef MM_DEBUG
|
|
dbgprintf("MM: ~PageDirectory K%x\n", this);
|
|
#endif
|
|
InterruptDisabler disabler;
|
|
pdb_map().remove(m_directory_page->paddr().get());
|
|
}
|
|
|
|
void PageDirectory::flush(VirtualAddress vaddr)
|
|
{
|
|
#ifdef MM_DEBUG
|
|
dbgprintf("MM: Flush page V%p\n", vaddr.get());
|
|
#endif
|
|
if (!current)
|
|
return;
|
|
if (this == &MM.kernel_page_directory() || ¤t->process().page_directory() == this)
|
|
MM.flush_tlb(vaddr);
|
|
}
|