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
9 /* INCLUDES *******************************************************************/
15 #line 15 "ARMĀ³::IOSUP"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
19 /* GLOBALS ********************************************************************/
22 // Each architecture has its own caching attributes for both I/O and Physical
25 // This describes the attributes for the x86 architecture. It eventually needs
26 // to go in the appropriate i386 directory.
28 MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes
[2][MmMaximumCacheType
] =
33 {MiNonCached
,MiCached
,MiWriteCombined
,MiCached
,MiNonCached
,MiWriteCombined
},
38 {MiNonCached
,MiCached
,MiWriteCombined
,MiCached
,MiNonCached
,MiWriteCombined
},
41 /* PUBLIC FUNCTIONS ***********************************************************/
48 MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress
,
49 IN ULONG NumberOfBytes
,
50 IN MEMORY_CACHING_TYPE CacheType
)
53 PFN_TYPE Pfn
, PageCount
;
58 MI_PFN_CACHE_ATTRIBUTE CacheAttribute
;
62 // Normalize and validate the caching attributes
65 if (CacheType
>= MmMaximumCacheType
) return NULL
;
68 // Calculate page count
70 PageCount
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress
.LowPart
,
74 // Compute the PFN and check if it's a known I/O mapping
75 // Also translate the cache attribute
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
];
83 // Now allocate system PTEs for the mapping, and get the VA
85 PointerPte
= MiReserveSystemPtes(PageCount
, SystemPteSpace
);
86 if (!PointerPte
) return NULL
;
87 BaseAddress
= MiPteToAddress(PointerPte
);
90 // Check if this is uncached
92 if (CacheAttribute
!= MiCached
)
97 KeFlushEntireTb(TRUE
, TRUE
);
98 KeInvalidateAllCaches();
102 // Now compute the VA offset
104 BaseAddress
= (PVOID
)((ULONG_PTR
)BaseAddress
+
105 BYTE_OFFSET(PhysicalAddress
.LowPart
));
108 // Get the template and configure caching
110 TempPte
= HyperTemplatePte
;
111 switch (CacheAttribute
)
118 MI_PAGE_DISABLE_CACHE(&TempPte
);
119 MI_PAGE_WRITE_THROUGH(&TempPte
);
129 case MiWriteCombined
:
132 // We don't support write combining yet
140 // Should never happen
147 // Sanity check and re-flush
149 Pfn
= (PFN_NUMBER
)(PhysicalAddress
.QuadPart
>> PAGE_SHIFT
);
150 ASSERT((Pfn1
== MiGetPfnEntry(Pfn
)) || (Pfn1
== NULL
));
151 KeFlushEntireTb(TRUE
, TRUE
);
152 KeInvalidateAllCaches();
160 // Start out with nothing
162 ASSERT(PointerPte
->u
.Hard
.Valid
== 0);
167 TempPte
.u
.Hard
.PageFrameNumber
= Pfn
++;
168 *PointerPte
++ = TempPte
;
169 } while (--PageCount
);
182 MmUnmapIoSpace(IN PVOID BaseAddress
,
183 IN ULONG NumberOfBytes
)
185 PFN_NUMBER PageCount
, Pfn
;
191 ASSERT(NumberOfBytes
!= 0);
194 // Get the page count
196 PageCount
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress
, NumberOfBytes
);
199 // Get the PTE and PFN
201 PointerPte
= MiAddressToPte(BaseAddress
);
202 Pfn
= PFN_FROM_PTE(PointerPte
);
205 // Is this an I/O mapping?
207 if (Pfn
> MmHighestPhysicalPage
)
212 RtlZeroMemory(PointerPte
, PageCount
* sizeof(MMPTE
));
217 KeFlushEntireTb(TRUE
, TRUE
);
223 MiReleaseSystemPtes(PointerPte
, PageCount
, 0);
231 MmMapVideoDisplay(IN PHYSICAL_ADDRESS PhysicalAddress
,
232 IN ULONG NumberOfBytes
,
233 IN MEMORY_CACHING_TYPE CacheType
)
238 // Call the real function
240 return MmMapIoSpace(PhysicalAddress
, NumberOfBytes
, CacheType
);
248 MmUnmapVideoDisplay(IN PVOID BaseAddress
,
249 IN ULONG NumberOfBytes
)
252 // Call the real function
254 MmUnmapIoSpace(BaseAddress
, NumberOfBytes
);