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