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