xref: /haiku/src/system/kernel/arch/m68k/paging/040/M68KPagingMethod040.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
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