- Use the new portable flag definitions.
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / iosup.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/iosup.c
5 * PURPOSE: ARM Memory Manager I/O Mapping Functionality
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #line 15 "ARMĀ³::IOSUP"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
18
19 /* GLOBALS ********************************************************************/
20
21 //
22 // Each architecture has its own caching attributes for both I/O and Physical
23 // memory mappings.
24 //
25 // This describes the attributes for the x86 architecture. It eventually needs
26 // to go in the appropriate i386 directory.
27 //
28 MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType] =
29 {
30 //
31 // RAM
32 //
33 {MiNonCached,MiCached,MiWriteCombined,MiCached,MiNonCached,MiWriteCombined},
34
35 //
36 // Device Memory
37 //
38 {MiNonCached,MiCached,MiWriteCombined,MiCached,MiNonCached,MiWriteCombined},
39 };
40
41 /* PUBLIC FUNCTIONS ***********************************************************/
42
43 /*
44 * @implemented
45 */
46 PVOID
47 NTAPI
48 MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress,
49 IN ULONG NumberOfBytes,
50 IN MEMORY_CACHING_TYPE CacheType)
51 {
52
53 PFN_TYPE Pfn, PageCount;
54 PMMPTE PointerPte;
55 PVOID BaseAddress;
56 MMPTE TempPte;
57 PMMPFN Pfn1 = NULL;
58 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
59 BOOLEAN IsIoMapping;
60
61 //
62 // Normalize and validate the caching attributes
63 //
64 CacheType &= 0xFF;
65 if (CacheType >= MmMaximumCacheType) return NULL;
66
67 //
68 // Calculate page count
69 //
70 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress.LowPart,
71 NumberOfBytes);
72
73 //
74 // Compute the PFN and check if it's a known I/O mapping
75 // Also translate the cache attribute
76 //
77 Pfn = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
78 IsIoMapping = (Pfn > MmHighestPhysicalPage) ? TRUE : FALSE;
79 if (!IsIoMapping) Pfn1 = MiGetPfnEntry(Pfn);
80 CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
81
82 //
83 // Now allocate system PTEs for the mapping, and get the VA
84 //
85 PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
86 if (!PointerPte) return NULL;
87 BaseAddress = MiPteToAddress(PointerPte);
88
89 //
90 // Check if this is uncached
91 //
92 if (CacheAttribute != MiCached)
93 {
94 //
95 // Flush all caches
96 //
97 KeFlushEntireTb(TRUE, TRUE);
98 KeInvalidateAllCaches();
99 }
100
101 //
102 // Now compute the VA offset
103 //
104 BaseAddress = (PVOID)((ULONG_PTR)BaseAddress +
105 BYTE_OFFSET(PhysicalAddress.LowPart));
106
107 //
108 // Get the template and configure caching
109 //
110 TempPte = HyperTemplatePte;
111 switch (CacheAttribute)
112 {
113 case MiNonCached:
114
115 //
116 // Disable the cache
117 //
118 MI_PAGE_DISABLE_CACHE(&TempPte);
119 MI_PAGE_WRITE_THROUGH(&TempPte);
120 break;
121
122 case MiCached:
123
124 //
125 // Leave defaults
126 //
127 break;
128
129 case MiWriteCombined:
130
131 //
132 // We don't support write combining yet
133 //
134 ASSERT(FALSE);
135 break;
136
137 default:
138
139 //
140 // Should never happen
141 //
142 ASSERT(FALSE);
143 break;
144 }
145
146 //
147 // Sanity check and re-flush
148 //
149 Pfn = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
150 ASSERT((Pfn1 == MiGetPfnEntry(Pfn)) || (Pfn1 == NULL));
151 KeFlushEntireTb(TRUE, TRUE);
152 KeInvalidateAllCaches();
153
154 //
155 // Do the mapping
156 //
157 do
158 {
159 //
160 // Start out with nothing
161 //
162 ASSERT(PointerPte->u.Hard.Valid == 0);
163
164 //
165 // Write the PFN
166 //
167 TempPte.u.Hard.PageFrameNumber = Pfn++;
168 *PointerPte++ = TempPte;
169 } while (--PageCount);
170
171 //
172 // We're done!
173 //
174 return BaseAddress;
175 }
176
177 /*
178 * @implemented
179 */
180 VOID
181 NTAPI
182 MmUnmapIoSpace(IN PVOID BaseAddress,
183 IN ULONG NumberOfBytes)
184 {
185 PFN_NUMBER PageCount, Pfn;
186 PMMPTE PointerPte;
187
188 //
189 // Sanity check
190 //
191 ASSERT(NumberOfBytes != 0);
192
193 //
194 // Get the page count
195 //
196 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, NumberOfBytes);
197
198 //
199 // Get the PTE and PFN
200 //
201 PointerPte = MiAddressToPte(BaseAddress);
202 Pfn = PFN_FROM_PTE(PointerPte);
203
204 //
205 // Is this an I/O mapping?
206 //
207 if (Pfn > MmHighestPhysicalPage)
208 {
209 //
210 // Destroy the PTE
211 //
212 RtlZeroMemory(PointerPte, PageCount * sizeof(MMPTE));
213
214 //
215 // Blow the TLB
216 //
217 KeFlushEntireTb(TRUE, TRUE);
218 }
219
220 //
221 // Release the PTEs
222 //
223 MiReleaseSystemPtes(PointerPte, PageCount, 0);
224 }
225
226 /*
227 * @implemented
228 */
229 PVOID
230 NTAPI
231 MmMapVideoDisplay(IN PHYSICAL_ADDRESS PhysicalAddress,
232 IN ULONG NumberOfBytes,
233 IN MEMORY_CACHING_TYPE CacheType)
234 {
235 PAGED_CODE();
236
237 //
238 // Call the real function
239 //
240 return MmMapIoSpace(PhysicalAddress, NumberOfBytes, CacheType);
241 }
242
243 /*
244 * @implemented
245 */
246 VOID
247 NTAPI
248 MmUnmapVideoDisplay(IN PVOID BaseAddress,
249 IN ULONG NumberOfBytes)
250 {
251 //
252 // Call the real function
253 //
254 MmUnmapIoSpace(BaseAddress, NumberOfBytes);
255 }
256
257 /* EOF */