xref: /haiku/src/system/kernel/arch/ppc/paging/460/PPCPagingMethod460.h (revision d66182742ff26552a05d04cf3c5d5c47a7b622ca)
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