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