Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhypermap.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: ntoskrnl/mm/ARM3/hypermap.c 00005 * PURPOSE: ARM Memory Manager Hyperspace Mapping Functionality 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 #define MODULE_INVOLVED_IN_ARM3 00016 #include "../ARM3/miarm.h" 00017 00018 /* GLOBALS ********************************************************************/ 00019 00020 PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte; 00021 PMMPTE MiFirstReservedZeroingPte; 00022 MMPTE HyperTemplatePte; 00023 PEPROCESS HyperProcess; 00024 KIRQL HyperIrql; 00025 00026 /* PRIVATE FUNCTIONS **********************************************************/ 00027 00028 PVOID 00029 NTAPI 00030 MiMapPageInHyperSpace(IN PEPROCESS Process, 00031 IN PFN_NUMBER Page, 00032 IN PKIRQL OldIrql) 00033 { 00034 MMPTE TempPte; 00035 PMMPTE PointerPte; 00036 PFN_NUMBER Offset; 00037 00038 // 00039 // Never accept page 0 or non-physical pages 00040 // 00041 ASSERT(Page != 0); 00042 ASSERT(MiGetPfnEntry(Page) != NULL); 00043 00044 // 00045 // Build the PTE 00046 // 00047 TempPte = ValidKernelPte; 00048 TempPte.u.Hard.PageFrameNumber = Page; 00049 MI_MAKE_LOCAL_PAGE(&TempPte); // Hyperspace is local! 00050 00051 // 00052 // Pick the first hyperspace PTE 00053 // 00054 PointerPte = MmFirstReservedMappingPte; 00055 00056 // 00057 // Acquire the hyperlock 00058 // 00059 ASSERT(Process == PsGetCurrentProcess()); 00060 KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql); 00061 00062 // 00063 // Now get the first free PTE 00064 // 00065 Offset = PFN_FROM_PTE(PointerPte); 00066 if (!Offset) 00067 { 00068 // 00069 // Reset the PTEs 00070 // 00071 Offset = MI_HYPERSPACE_PTES; 00072 KeFlushProcessTb(); 00073 } 00074 00075 // 00076 // Prepare the next PTE 00077 // 00078 PointerPte->u.Hard.PageFrameNumber = Offset - 1; 00079 00080 // 00081 // Write the current PTE 00082 // 00083 PointerPte += Offset; 00084 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00085 00086 // 00087 // Return the address 00088 // 00089 return MiPteToAddress(PointerPte); 00090 } 00091 00092 VOID 00093 NTAPI 00094 MiUnmapPageInHyperSpace(IN PEPROCESS Process, 00095 IN PVOID Address, 00096 IN KIRQL OldIrql) 00097 { 00098 ASSERT(Process == PsGetCurrentProcess()); 00099 00100 // 00101 // Blow away the mapping 00102 // 00103 MiAddressToPte(Address)->u.Long = 0; 00104 00105 // 00106 // Release the hyperlock 00107 // 00108 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 00109 KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql); 00110 } 00111 00112 PVOID 00113 NTAPI 00114 MiMapPagesInZeroSpace(IN PMMPFN Pfn1, 00115 IN PFN_NUMBER NumberOfPages) 00116 { 00117 MMPTE TempPte; 00118 PMMPTE PointerPte; 00119 PFN_NUMBER Offset, PageFrameIndex; 00120 00121 // 00122 // Sanity checks 00123 // 00124 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00125 ASSERT(NumberOfPages != 0); 00126 ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1)); 00127 00128 // 00129 // Pick the first zeroing PTE 00130 // 00131 PointerPte = MiFirstReservedZeroingPte; 00132 00133 // 00134 // Now get the first free PTE 00135 // 00136 Offset = PFN_FROM_PTE(PointerPte); 00137 if (NumberOfPages > Offset) 00138 { 00139 // 00140 // Reset the PTEs 00141 // 00142 Offset = MI_ZERO_PTES - 1; 00143 PointerPte->u.Hard.PageFrameNumber = Offset; 00144 KeFlushProcessTb(); 00145 } 00146 00147 // 00148 // Prepare the next PTE 00149 // 00150 PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages; 00151 00152 /* Choose the correct PTE to use, and which template */ 00153 PointerPte += (Offset + 1); 00154 TempPte = ValidKernelPte; 00155 00156 /* Make sure the list isn't empty and loop it */ 00157 ASSERT(Pfn1 != (PVOID)LIST_HEAD); 00158 while (Pfn1 != (PVOID)LIST_HEAD) 00159 { 00160 /* Get the page index for this PFN */ 00161 PageFrameIndex = MiGetPfnEntryIndex(Pfn1); 00162 00163 // 00164 // Write the PFN 00165 // 00166 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00167 00168 // 00169 // Set the correct PTE to write to, and set its new value 00170 // 00171 PointerPte--; 00172 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00173 00174 /* Move to the next PFN */ 00175 Pfn1 = (PMMPFN)Pfn1->u1.Flink; 00176 } 00177 00178 // 00179 // Return the address 00180 // 00181 return MiPteToAddress(PointerPte); 00182 } 00183 00184 VOID 00185 NTAPI 00186 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, 00187 IN PFN_NUMBER NumberOfPages) 00188 { 00189 PMMPTE PointerPte; 00190 00191 // 00192 // Sanity checks 00193 // 00194 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00195 ASSERT (NumberOfPages != 0); 00196 ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1)); 00197 00198 // 00199 // Get the first PTE for the mapped zero VA 00200 // 00201 PointerPte = MiAddressToPte(VirtualAddress); 00202 00203 // 00204 // Blow away the mapped zero PTEs 00205 // 00206 RtlZeroMemory(PointerPte, NumberOfPages * sizeof(MMPTE)); 00207 } 00208 Generated on Fri May 25 2012 04:35:57 for ReactOS by
1.7.6.1
|