20 #include "VirtualAddressSpace.h" 21 #include "HashedPageTable.h" 22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/machine/openfirmware/Device.h" 24 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h" 25 #include "pedigree/kernel/panic.h" 26 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 27 #include "pedigree/kernel/processor/Processor.h" 28 #include "pedigree/kernel/processor/types.h" 29 #include "pedigree/kernel/utilities/utility.h" 31 #define PAGE_DIRECTORY_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 22) & 0x3FF) 32 #define PAGE_TABLE_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 12) & 0x3FF) 44 p->
m_Heap =
reinterpret_cast<void *
>(USERSPACE_VIRTUAL_HEAP);
45 p->
m_HeapEnd =
reinterpret_cast<void *
>(USERSPACE_VIRTUAL_HEAP);
66 for (
int i = 0; i < 1024; i++)
77 OFDevice mmu(chosen.getProperty(
"mmu"));
82 panic(
"Couldn't find anywhere to load the initial page tables!");
88 KERNEL_INITIAL_PAGE_TABLES, phys, 0x100000, 0x6a);
90 OFParam ret = mmu.executeMethod(
91 "map", 4, reinterpret_cast<OFParam>(-1),
92 reinterpret_cast<OFParam>(0x100000),
93 reinterpret_cast<OFParam>(KERNEL_INITIAL_PAGE_TABLES),
94 reinterpret_cast<OFParam>(phys));
95 if (ret == reinterpret_cast<OFParam>(-1))
96 panic(
"Kernel page table mapping failed");
100 reinterpret_cast<uint8_t *>(KERNEL_INITIAL_PAGE_TABLES), 0, 0x100000);
104 for (
int i = 0; i < 0x100; i++)
106 KERNEL_INITIAL_PAGE_TABLES + i * 0x1000);
114 panic(
"initialRoster() called on a VA space that is not the kernel " 122 for (
unsigned int j = 0; j < t.size; j += 0x1000)
124 void *virtualAddress =
reinterpret_cast<void *
>(t.virt + j);
127 uint32_t mode = t.mode;
144 reinterpret_cast<uint8_t *>(pTable), 0,
149 pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] =
150 (physicalAddress & 0xFFFFF000) | newMode;
164 uintptr_t addr =
reinterpret_cast<uintptr_t
>(virtualAddress);
177 uint32_t pte = pTable->entries[PAGE_TABLE_INDEX(virtualAddress)];
187 physical_uintptr_t
physicalAddress,
void *virtualAddress,
size_t flags)
191 uintptr_t addr =
reinterpret_cast<uintptr_t
>(virtualAddress);
210 if (pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] != 0)
214 pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] =
215 (physicalAddress & 0xFFFFF000) | flags;
219 addr, physicalAddress, flags,
m_Vsid * 8 + (addr >> 28));
225 void *virtualAddress, physical_uintptr_t &
physicalAddress,
size_t &flags)
229 uintptr_t addr =
reinterpret_cast<uintptr_t
>(virtualAddress);
242 uint32_t pte = pTable->entries[PAGE_TABLE_INDEX(virtualAddress)];
244 physicalAddress = pte & 0xFFF;
245 flags = pte & 0xFFFFF000;
252 uintptr_t addr =
reinterpret_cast<uintptr_t
>(virtualAddress);
265 pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] &= 0xFFFFF000;
266 pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] |= newFlags & 0xFFF;
273 uintptr_t addr =
reinterpret_cast<uintptr_t
>(virtualAddress);
286 pTable->entries[PAGE_TABLE_INDEX(virtualAddress)] = 0;
290 reinterpret_cast<uint32_t>(virtualAddress),
m_Vsid * 8 + (addr >> 28));
295 uint8_t *pStackTop =
new uint8_t[0x4000];
297 return pStackTop + 0x4000 - 4;
299 void PPC32VirtualAddressSpace::freeStack(
void *pStack)
309 for (uint64_t i = 0; i < 1024; i++)
311 if (i * 1024ULL * 4096ULL >= KERNEL_SPACE_START)
317 for (
int j = 0; j < 1024; j++)
319 if (pPageTable->entries[j] == 0)
322 void *virtualAddress =
323 reinterpret_cast<void *
>(((i * 1024) + j) * 4096);
324 uint32_t flags = pPageTable->entries[j] & 0xFFF;
328 physical_uintptr_t newFrame =
332 map(newFrame, KERNEL_VIRTUAL_TEMP1,
337 MemoryCopy(KERNEL_VIRTUAL_TEMP1, virtualAddress, 0x1000);
340 unmap(KERNEL_VIRTUAL_TEMP1);
343 newAS->
map(newFrame, virtualAddress, flags);
353 for (uint64_t i = 0; i < 1024; i++)
355 if (i * 1024ULL * 4096ULL >= KERNEL_SPACE_START)
361 for (
int j = 0; j < 1024; j++)
367 if (pPageTable->entries[j] == 0)
370 unmap(reinterpret_cast<void *>(((i * 1024) + j) * 4096));
static HashedPageTable & instance()
static PPC32VirtualAddressSpace m_KernelSpace
virtual void * allocateStack()
static PhysicalMemoryManager & instance()
virtual void setFlags(void *virtualAddress, size_t newFlags)
static OpenFirmware & instance()
void returnVsid(Vsid vsid)
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
static const size_t WriteThrough
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
virtual bool isAddressValid(void *virtualAddress)
void addMapping(uint32_t effectiveAddress, uint32_t physicalAddress, uint32_t mode, uint32_t vsid)
void removeMapping(uint32_t effectiveAddress, uint32_t vsid)
static const size_t Write
static VirtualAddressSpace * create()
uintptr_t physicalAddress(physical_uintptr_t address) PURE
static const size_t KernelMode
virtual VirtualAddressSpace * clone()
bool initialise(Translations &translations)
virtual void unmap(void *virtualAddress)
virtual ~PPC32VirtualAddressSpace()
virtual void revertToKernelAddressSpace()
ShadowPageTable * m_pPageDirectory[1024]
Translation getTranslation(size_t n)
static VsidManager & instance()
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)
virtual bool isMapped(void *virtualAddress)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)
void addTranslation(uint32_t virt, uint32_t phys, uint32_t size, uint32_t mode)
static const size_t CacheDisable
void initialRoster(Translations &translations)
uint32_t findFreePhysicalMemory(uint32_t size, uint32_t align=0x100000)
PPC32VirtualAddressSpace()
size_t getNumTranslations()