1*d6618274SFrançois Revol /* 2*d6618274SFrançois Revol * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3*d6618274SFrançois Revol * Distributed under the terms of the MIT License. 4*d6618274SFrançois Revol */ 5*d6618274SFrançois Revol #ifndef KERNEL_ARCH_PPC_PAGING_460_PPC_PAGING_METHOD_460_H 6*d6618274SFrançois Revol #define KERNEL_ARCH_PPC_PAGING_460_PPC_PAGING_METHOD_460_H 7*d6618274SFrançois Revol 8*d6618274SFrançois Revol 9*d6618274SFrançois Revol #include <arch_mmu.h> 10*d6618274SFrançois Revol //#include "paging/460/paging.h" 11*d6618274SFrançois Revol #include "paging/PPCPagingMethod.h" 12*d6618274SFrançois Revol #include "paging/PPCPagingStructures.h" 13*d6618274SFrançois Revol #include "GenericVMPhysicalPageMapper.h" 14*d6618274SFrançois Revol 15*d6618274SFrançois Revol 16*d6618274SFrançois Revol class TranslationMapPhysicalPageMapper; 17*d6618274SFrançois Revol 18*d6618274SFrançois Revol 19*d6618274SFrançois Revol class PPCPagingMethod460 : public PPCPagingMethod { 20*d6618274SFrançois Revol public: 21*d6618274SFrançois Revol PPCPagingMethod460(); 22*d6618274SFrançois Revol virtual ~PPCPagingMethod460(); 23*d6618274SFrançois Revol 24*d6618274SFrançois Revol virtual status_t Init(kernel_args* args, 25*d6618274SFrançois Revol VMPhysicalPageMapper** _physicalPageMapper); 26*d6618274SFrançois Revol virtual status_t InitPostArea(kernel_args* args); 27*d6618274SFrançois Revol 28*d6618274SFrançois Revol virtual status_t CreateTranslationMap(bool kernel, 29*d6618274SFrançois Revol VMTranslationMap** _map); 30*d6618274SFrançois Revol 31*d6618274SFrançois Revol virtual status_t MapEarly(kernel_args* args, 32*d6618274SFrançois Revol addr_t virtualAddress, 33*d6618274SFrançois Revol phys_addr_t physicalAddress, 34*d6618274SFrançois Revol uint8 attributes, 35*d6618274SFrançois Revol page_num_t (*get_free_page)(kernel_args*)); 36*d6618274SFrançois Revol 37*d6618274SFrançois Revol virtual bool IsKernelPageAccessible(addr_t virtualAddress, 38*d6618274SFrançois Revol uint32 protection); 39*d6618274SFrançois Revol #if 0//X86 40*d6618274SFrançois Revol inline page_table_entry* PageHole() const 41*d6618274SFrançois Revol { return fPageHole; } 42*d6618274SFrançois Revol inline page_directory_entry* PageHolePageDir() const 43*d6618274SFrançois Revol { return fPageHolePageDir; } 44*d6618274SFrançois Revol inline uint32 KernelPhysicalPageDirectory() const 45*d6618274SFrançois Revol { return fKernelPhysicalPageDirectory; } 46*d6618274SFrançois Revol inline page_directory_entry* KernelVirtualPageDirectory() const 47*d6618274SFrançois Revol { return fKernelVirtualPageDirectory; } 48*d6618274SFrançois Revol inline PPCPhysicalPageMapper* PhysicalPageMapper() const 49*d6618274SFrançois Revol { return fPhysicalPageMapper; } 50*d6618274SFrançois Revol inline TranslationMapPhysicalPageMapper* KernelPhysicalPageMapper() const 51*d6618274SFrançois Revol { return fKernelPhysicalPageMapper; } 52*d6618274SFrançois Revol #endif 53*d6618274SFrançois Revol 54*d6618274SFrançois Revol inline page_table_entry_group* PageTable() const 55*d6618274SFrançois Revol { return fPageTable; } 56*d6618274SFrançois Revol inline size_t PageTableSize() const 57*d6618274SFrançois Revol { return fPageTableSize; } 58*d6618274SFrançois Revol inline uint32 PageTableHashMask() const 59*d6618274SFrançois Revol { return fPageTableHashMask; } 60*d6618274SFrançois Revol 61*d6618274SFrançois Revol static PPCPagingMethod460* Method(); 62*d6618274SFrançois Revol 63*d6618274SFrançois Revol void FillPageTableEntry(page_table_entry *entry, 64*d6618274SFrançois Revol uint32 virtualSegmentID, 65*d6618274SFrançois Revol addr_t virtualAddress, 66*d6618274SFrançois Revol phys_addr_t physicalAddress, 67*d6618274SFrançois Revol uint8 protection, uint32 memoryType, 68*d6618274SFrançois Revol bool secondaryHash); 69*d6618274SFrançois Revol 70*d6618274SFrançois Revol 71*d6618274SFrançois Revol #if 0//X86 72*d6618274SFrançois Revol static void PutPageTableInPageDir( 73*d6618274SFrançois Revol page_directory_entry* entry, 74*d6618274SFrançois Revol phys_addr_t pgtablePhysical, 75*d6618274SFrançois Revol uint32 attributes); 76*d6618274SFrançois Revol static void PutPageTableEntryInTable( 77*d6618274SFrançois Revol page_table_entry* entry, 78*d6618274SFrançois Revol phys_addr_t physicalAddress, 79*d6618274SFrançois Revol uint32 attributes, uint32 memoryType, 80*d6618274SFrançois Revol bool globalPage); 81*d6618274SFrançois Revol static page_table_entry SetPageTableEntry(page_table_entry* entry, 82*d6618274SFrançois Revol page_table_entry newEntry); 83*d6618274SFrançois Revol static page_table_entry SetPageTableEntryFlags(page_table_entry* entry, 84*d6618274SFrançois Revol uint32 flags); 85*d6618274SFrançois Revol static page_table_entry TestAndSetPageTableEntry( 86*d6618274SFrançois Revol page_table_entry* entry, 87*d6618274SFrançois Revol page_table_entry newEntry, 88*d6618274SFrançois Revol page_table_entry oldEntry); 89*d6618274SFrançois Revol static page_table_entry ClearPageTableEntry(page_table_entry* entry); 90*d6618274SFrançois Revol static page_table_entry ClearPageTableEntryFlags( 91*d6618274SFrançois Revol page_table_entry* entry, uint32 flags); 92*d6618274SFrançois Revol 93*d6618274SFrançois Revol static uint32 MemoryTypeToPageTableEntryFlags( 94*d6618274SFrançois Revol uint32 memoryType); 95*d6618274SFrançois Revol #endif 96*d6618274SFrançois Revol 97*d6618274SFrançois Revol private: 98*d6618274SFrançois Revol //XXX:x86 99*d6618274SFrançois Revol struct PhysicalPageSlotPool; 100*d6618274SFrançois Revol friend struct PhysicalPageSlotPool; 101*d6618274SFrançois Revol 102*d6618274SFrançois Revol private: 103*d6618274SFrançois Revol #if 0//X86 104*d6618274SFrançois Revol static void _EarlyPreparePageTables( 105*d6618274SFrançois Revol page_table_entry* pageTables, 106*d6618274SFrançois Revol addr_t address, size_t size); 107*d6618274SFrançois Revol static status_t _EarlyQuery(addr_t virtualAddress, 108*d6618274SFrançois Revol phys_addr_t *_physicalAddress); 109*d6618274SFrançois Revol #endif 110*d6618274SFrançois Revol 111*d6618274SFrançois Revol private: 112*d6618274SFrançois Revol struct page_table_entry_group *fPageTable; 113*d6618274SFrançois Revol size_t fPageTableSize; 114*d6618274SFrançois Revol uint32 fPageTableHashMask; 115*d6618274SFrançois Revol area_id fPageTableArea; 116*d6618274SFrançois Revol 117*d6618274SFrançois Revol GenericVMPhysicalPageMapper fPhysicalPageMapper; 118*d6618274SFrançois Revol 119*d6618274SFrançois Revol 120*d6618274SFrançois Revol #if 0 //XXX:x86 121*d6618274SFrançois Revol page_table_entry* fPageHole; 122*d6618274SFrançois Revol page_directory_entry* fPageHolePageDir; 123*d6618274SFrançois Revol uint32 fKernelPhysicalPageDirectory; 124*d6618274SFrançois Revol page_directory_entry* fKernelVirtualPageDirectory; 125*d6618274SFrançois Revol PPCPhysicalPageMapper* fPhysicalPageMapper; 126*d6618274SFrançois Revol TranslationMapPhysicalPageMapper* fKernelPhysicalPageMapper; 127*d6618274SFrançois Revol #endif 128*d6618274SFrançois Revol }; 129*d6618274SFrançois Revol 130*d6618274SFrançois Revol 131*d6618274SFrançois Revol /*static*/ inline PPCPagingMethod460* 132*d6618274SFrançois Revol PPCPagingMethod460::Method() 133*d6618274SFrançois Revol { 134*d6618274SFrançois Revol return static_cast<PPCPagingMethod460*>(gPPCPagingMethod); 135*d6618274SFrançois Revol } 136*d6618274SFrançois Revol 137*d6618274SFrançois Revol 138*d6618274SFrançois Revol #if 0//X86 139*d6618274SFrançois Revol /*static*/ inline page_table_entry 140*d6618274SFrançois Revol PPCPagingMethod460::SetPageTableEntry(page_table_entry* entry, 141*d6618274SFrançois Revol page_table_entry newEntry) 142*d6618274SFrançois Revol { 143*d6618274SFrançois Revol return atomic_set((int32*)entry, newEntry); 144*d6618274SFrançois Revol } 145*d6618274SFrançois Revol 146*d6618274SFrançois Revol 147*d6618274SFrançois Revol /*static*/ inline page_table_entry 148*d6618274SFrançois Revol PPCPagingMethod460::SetPageTableEntryFlags(page_table_entry* entry, 149*d6618274SFrançois Revol uint32 flags) 150*d6618274SFrançois Revol { 151*d6618274SFrançois Revol return atomic_or((int32*)entry, flags); 152*d6618274SFrançois Revol } 153*d6618274SFrançois Revol 154*d6618274SFrançois Revol 155*d6618274SFrançois Revol /*static*/ inline page_table_entry 156*d6618274SFrançois Revol PPCPagingMethod460::TestAndSetPageTableEntry(page_table_entry* entry, 157*d6618274SFrançois Revol page_table_entry newEntry, page_table_entry oldEntry) 158*d6618274SFrançois Revol { 159*d6618274SFrançois Revol return atomic_test_and_set((int32*)entry, newEntry, oldEntry); 160*d6618274SFrançois Revol } 161*d6618274SFrançois Revol 162*d6618274SFrançois Revol 163*d6618274SFrançois Revol /*static*/ inline page_table_entry 164*d6618274SFrançois Revol PPCPagingMethod460::ClearPageTableEntry(page_table_entry* entry) 165*d6618274SFrançois Revol { 166*d6618274SFrançois Revol return SetPageTableEntry(entry, 0); 167*d6618274SFrançois Revol } 168*d6618274SFrançois Revol 169*d6618274SFrançois Revol 170*d6618274SFrançois Revol /*static*/ inline page_table_entry 171*d6618274SFrançois Revol PPCPagingMethod460::ClearPageTableEntryFlags(page_table_entry* entry, uint32 flags) 172*d6618274SFrançois Revol { 173*d6618274SFrançois Revol return atomic_and((int32*)entry, ~flags); 174*d6618274SFrançois Revol } 175*d6618274SFrançois Revol 176*d6618274SFrançois Revol 177*d6618274SFrançois Revol /*static*/ inline uint32 178*d6618274SFrançois Revol PPCPagingMethod460::MemoryTypeToPageTableEntryFlags(uint32 memoryType) 179*d6618274SFrançois Revol { 180*d6618274SFrançois Revol // ATM we only handle the uncacheable and write-through type explicitly. For 181*d6618274SFrançois Revol // all other types we rely on the MTRRs to be set up correctly. Since we set 182*d6618274SFrançois Revol // the default memory type to write-back and since the uncacheable type in 183*d6618274SFrançois Revol // the PTE overrides any MTRR attribute (though, as per the specs, that is 184*d6618274SFrançois Revol // not recommended for performance reasons), this reduces the work we 185*d6618274SFrançois Revol // actually *have* to do with the MTRRs to setting the remaining types 186*d6618274SFrançois Revol // (usually only write-combining for the frame buffer). 187*d6618274SFrançois Revol switch (memoryType) { 188*d6618274SFrançois Revol case B_MTR_UC: 189*d6618274SFrançois Revol return PPC_PTE_CACHING_DISABLED | PPC_PTE_WRITE_THROUGH; 190*d6618274SFrançois Revol 191*d6618274SFrançois Revol case B_MTR_WC: 192*d6618274SFrançois Revol // PPC_PTE_WRITE_THROUGH would be closer, but the combination with 193*d6618274SFrançois Revol // MTRR WC is "implementation defined" for Pentium Pro/II. 194*d6618274SFrançois Revol return 0; 195*d6618274SFrançois Revol 196*d6618274SFrançois Revol case B_MTR_WT: 197*d6618274SFrançois Revol return PPC_PTE_WRITE_THROUGH; 198*d6618274SFrançois Revol 199*d6618274SFrançois Revol case B_MTR_WP: 200*d6618274SFrançois Revol case B_MTR_WB: 201*d6618274SFrançois Revol default: 202*d6618274SFrançois Revol return 0; 203*d6618274SFrançois Revol } 204*d6618274SFrançois Revol } 205*d6618274SFrançois Revol #endif//X86 206*d6618274SFrançois Revol 207*d6618274SFrançois Revol 208*d6618274SFrançois Revol #endif // KERNEL_ARCH_PPC_PAGING_460_PPC_PAGING_METHOD_460_H 209