ladybird/Kernel/MemoryManager.h

131 lines
3.4 KiB
C++

#pragma once
#include <AK/Types.h>
class PhysicalAddress {
public:
PhysicalAddress() { }
explicit PhysicalAddress(dword address) : m_address(address) { }
dword get() const { return m_address; }
void set(dword address) { m_address = address; }
void mask(dword m) { m_address &= m; }
private:
dword m_address { 0 };
};
class LinearAddress {
public:
LinearAddress() { }
explicit LinearAddress(dword address) : m_address(address) { }
LinearAddress offset(dword o) const { return LinearAddress(m_address + o); }
dword get() const { return m_address; }
void set(dword address) { m_address = address; }
void mask(dword m) { m_address &= m; }
bool operator==(const LinearAddress& other) const { return m_address == other.m_address; }
private:
dword m_address { 0 };
};
class MemoryManager {
public:
static MemoryManager& the();
PhysicalAddress pageDirectoryBase() const { return PhysicalAddress(reinterpret_cast<dword>(m_pageDirectory)); }
static void initialize();
private:
MemoryManager();
~MemoryManager();
void initializePaging();
void identityMap(LinearAddress, size_t length);
struct PageDirectoryEntry {
explicit PageDirectoryEntry(dword* pde) : m_pde(pde) { }
dword* pageTableBase() { return reinterpret_cast<dword*>(raw() & 0xfffff000u); }
void setPageTableBase(dword value)
{
*m_pde &= 0xfff;
*m_pde |= value & 0xfffff000;
}
dword raw() const { return *m_pde; }
dword* ptr() { return m_pde; }
enum Flags {
Present = 1 << 0,
ReadWrite = 1 << 1,
UserSupervisor = 1 << 2,
};
bool isPresent() const { return raw() & Present; }
void setPresent(bool b) { setBit(Present, b); }
bool isUserAllowed() const { return raw() & UserSupervisor; }
void setUserAllowed(bool b) { setBit(UserSupervisor, b); }
bool isWritable() const { return raw() & ReadWrite; }
void setWritable(bool b) { setBit(ReadWrite, b); }
void setBit(byte bit, bool value)
{
if (value)
*m_pde |= bit;
else
*m_pde &= ~bit;
}
dword* m_pde;
};
struct PageTableEntry {
explicit PageTableEntry(dword* pte) : m_pte(pte) { }
dword* physicalPageBase() { return reinterpret_cast<dword*>(raw() & 0xfffff000u); }
void setPhysicalPageBase(dword value)
{
*m_pte &= 0xfffu;
*m_pte |= value & 0xfffff000u;
}
dword raw() const { return *m_pte; }
dword* ptr() { return m_pte; }
enum Flags {
Present = 1 << 0,
ReadWrite = 1 << 1,
UserSupervisor = 1 << 2,
};
bool isPresent() const { return raw() & Present; }
void setPresent(bool b) { setBit(Present, b); }
bool isUserAllowed() const { return raw() & UserSupervisor; }
void setUserAllowed(bool b) { setBit(UserSupervisor, b); }
bool isWritable() const { return raw() & ReadWrite; }
void setWritable(bool b) { setBit(ReadWrite, b); }
void setBit(byte bit, bool value)
{
if (value)
*m_pte |= bit;
else
*m_pte &= ~bit;
}
dword* m_pte;
};
PageTableEntry ensurePTE(LinearAddress);
dword* m_pageDirectory;
dword* m_pageTableZero;
};