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