00058                    :
00059 
00060     This routine maps 
the specified physical section into 
the
00061     specified process's address space.
00062 
00063 Arguments:
00064 
00065     see 
MmMapViewOfSection above...
00066 
00067     ControlArea - Supplies 
the control area 
for the section.
00068 
00069     Process - Supplies 
the process pointer which 
is receiving 
the section.
00070 
00071     ProtectionMask - Supplies 
the initial page protection-mask.
00072 
00073     ReleasedWsMutex - Supplies 
FALSE, receives 
TRUE if the working set
00074                       mutex 
is released.
00075 
00076 Return Value:
00077 
00078     
Status of 
the map view operation.
00079 
00080 Environment:
00081 
00082     Kernel Mode, working set mutex and address creation mutex held.
00083 
00084 --*/
00085 
00086 {
00087     
PMMVAD Vad;
00088     PVOID StartingAddress;
00089     PVOID EndingAddress;
00090     KIRQL OldIrql;
00091     KIRQL OldIrql2;
00092     
PMMPTE PointerPpe;
00093     
PMMPTE PointerPde;
00094     
PMMPTE PointerPte;
00095     
PMMPTE LastPte;
00096     
MMPTE TempPte;
00097     
PMMPFN Pfn2;
00098     ULONG PhysicalViewSize;
00099     ULONG Alignment;
00100     ULONG PagesToMap;
00101     ULONG NextPfn;
00102     PVOID UsedPageTableHandle;
00103     PVOID UsedPageDirectoryHandle;
00104     
PMI_PHYSICAL_VIEW PhysicalView;
00105 
00106     
00107     
00108     
00109 
00110 
#ifdef FIRSTDBG
00111 
00112     
DbgPrint( 
"MM: Physsect CaptureBase = %x  SectionOffset = %x\n",
00113               CapturedBase, SectionOffset->LowPart );
00114     
DbgPrint( 
"MM: Physsect Allocation Type = %x, MEM_LARGE_PAGES = %x\n",
00115               AllocationType, MEM_LARGE_PAGES );
00116 
00117 
#endif //FIRSTDBG
00118 
00119     
00120     
00121     
00122     
00123     
00124     
00125     
00126     
00127     
00128 
00129     Alignment = 
X64K;
00130 
00131     
if( AllocationType & MEM_LARGE_PAGES ){
00132 
00133         
00134         
00135         
00136         
00137         
00138 
00139         ULONG MaxAlignment = 
MaximumAlignment( SectionOffset->LowPart );
00140 
00141         Alignment = (MaxAlignment > Alignment) ? MaxAlignment : Alignment;
00142 
00143 
#ifdef FIRSTDBG
00144 
00145         
DbgPrint( 
"MM: Alignment = %x, SectionOffset = %x\n",
00146                        Alignment, SectionOffset->LowPart );
00147 
00148 
#endif //FIRSTDBG
00149 
00150     }
00151 
00152 
00153     
LOCK_WS_UNSAFE (Process);
00154 
00155     
if (*CapturedBase == 
NULL) {
00156 
00157         
00158         
00159         
00160         
00161 
00162         
try {
00163 
00164             
00165             
00166             
00167 
00168 
00169             PhysicalViewSize = (SectionOffset->LowPart + *CapturedViewSize) -
00170                                (ULONG)
MI_64K_ALIGN(SectionOffset->LowPart);
00171             StartingAddress = 
MiFindEmptyAddressRange (PhysicalViewSize,
00172                                                        Alignment,
00173                                                        (ULONG)ZeroBits);
00174 
00175         } except (EXCEPTION_EXECUTE_HANDLER) {
00176 
00177             
return GetExceptionCode();
00178         }
00179 
00180         EndingAddress = (PVOID)(((ULONG)StartingAddress +
00181                                 PhysicalViewSize - 1
L) | (
PAGE_SIZE - 1
L));
00182         StartingAddress = (PVOID)((ULONG)StartingAddress +
00183                                      (SectionOffset->LowPart & (
X64K - 1)));
00184 
00185         
if (ZeroBits > 0) {
00186             
if (EndingAddress > (PVOID)((ULONG)0xFFFFFFFF >> ZeroBits)) {
00187                 
return STATUS_NO_MEMORY;
00188             }
00189         }
00190 
00191     } 
else {
00192 
00193         
00194         
00195         
00196         
00197 
00198         PhysicalViewSize = (SectionOffset->LowPart + *CapturedViewSize) -
00199                                 (ULONG)
MI_64K_ALIGN(SectionOffset->LowPart);
00200         StartingAddress = (PVOID)((ULONG)
MI_64K_ALIGN(*CapturedBase) +
00201                                     (SectionOffset->LowPart & (
X64K - 1)));
00202         EndingAddress = (PVOID)(((ULONG)StartingAddress +
00203                                 *CapturedViewSize - 1
L) | (
PAGE_SIZE - 1
L));
00204 
00205         Vad = 
MiCheckForConflictingVad (StartingAddress, EndingAddress);
00206         
if (Vad != (
PMMVAD)
NULL) {
00207 
#if 0
00208 
            MiDumpConflictingVad (StartingAddress, EndingAddress, Vad);
00209 
#endif
00210 
00211             
return STATUS_CONFLICTING_ADDRESSES;
00212         }
00213     }
00214 
00215     
00216     
00217     
00218     
00219 
00220     
00221     
00222     
00223     
00224     
00225 
00226     
try  {
00227 
00228         PhysicalView = (
PMI_PHYSICAL_VIEW)
ExAllocatePoolWithTag (NonPagedPool,
00229                                                                  
sizeof(
MI_PHYSICAL_VIEW),
00230                                                                  MI_PHYSICAL_VIEW_KEY);
00231         
if (PhysicalView == 
NULL) {
00232             
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
00233         }
00234 
00235         Vad = (
PMMVAD)
ExAllocatePoolWithTag (NonPagedPool, 
sizeof(
MMVAD), ' daV');
00236         
if (Vad == 
NULL) {
00237             
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
00238         }
00239 
00240         PhysicalView->
Vad = Vad;
00241         PhysicalView->
StartVa = StartingAddress;
00242         PhysicalView->
EndVa = EndingAddress;
00243 
00244         Vad->
StartingVpn = 
MI_VA_TO_VPN (StartingAddress);
00245         Vad->
EndingVpn = 
MI_VA_TO_VPN (EndingAddress);
00246         Vad->
ControlArea = ControlArea;
00247         Vad->
u.LongFlags = 0;
00248         Vad->
u2.VadFlags2.Inherit = ViewUnmap;
00249         Vad->
u.VadFlags.PhysicalMapping = 1;
00250         Vad->
u4.Banked = 
NULL;
00251         
00252         Vad->
u.VadFlags.Protection = ProtectionMask;
00253         Vad->
u2.VadFlags2.CopyOnWrite = 0;
00254         
00255         Vad->
FirstPrototypePte =
00256                        (
PMMPTE)(
MI_CONVERT_PHYSICAL_BUS_TO_PFN(*SectionOffset));
00257 
00258         
00259         
00260         
00261 
00262         Vad->
LastContiguousPte =
00263                        (
PMMPTE)(
MI_CONVERT_PHYSICAL_BUS_TO_PFN(*SectionOffset));
00264 
00265         
00266         
00267         
00268 
00269         
MiInsertVad (Vad);
00270 
00271     } except (EXCEPTION_EXECUTE_HANDLER) {
00272 
00273         
if (PhysicalView != 
NULL) {
00274             
ExFreePool (PhysicalView);
00275         }
00276 
00277         
if (Vad != (
PMMVAD)
NULL) {
00278 
00279             
00280             
00281             
00282             
00283             
00284 
00285             
ExFreePool (Vad);
00286             
return GetExceptionCode();
00287         }
00288         
return STATUS_INSUFFICIENT_RESOURCES;
00289     }
00290 
00291     
00292     
00293     
00294 
00295     
LOCK_AWE (Process, OldIrql);
00296     
LOCK_PFN2 (OldIrql2);
00297 
00298     InsertHeadList (&Process->PhysicalVadList, &PhysicalView->
ListEntry);
00299 
00300     ControlArea->NumberOfMappedViews += 1;
00301     ControlArea->NumberOfUserReferences += 1;
00302     
ASSERT (ControlArea->NumberOfSectionReferences != 0);
00303 
00304     
UNLOCK_PFN2 (OldIrql2);
00305     
UNLOCK_AWE (Process, OldIrql);
00306 
00307     
00308     
00309     
00310 
00311     PointerPpe = 
MiGetPpeAddress (StartingAddress);
00312     PointerPde = 
MiGetPdeAddress (StartingAddress);
00313     PointerPte = 
MiGetPteAddress (StartingAddress);
00314     LastPte = 
MiGetPteAddress (EndingAddress);
00315 
00316 
#if defined (_WIN64)
00317 
    MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE);
00318     
if (PointerPde->
u.Long == 0) {
00319         UsedPageDirectoryHandle = 
MI_GET_USED_PTES_HANDLE (PointerPte);
00320         
ASSERT (MI_GET_USED_PTES_FROM_HANDLE (UsedPageDirectoryHandle) == 0); 
00321         
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
00322     }
00323 
#endif
00324 
00325     
MiMakePdeExistAndMakeValid(PointerPde, Process, FALSE);
00326 
00327     Pfn2 = 
MI_PFN_ELEMENT(PointerPde->
u.Hard.PageFrameNumber);
00328 
00329     PagesToMap = ( ((ULONG)EndingAddress - (ULONG)StartingAddress)
00330                    + (
PAGE_SIZE-1) ) >> 
PAGE_SHIFT;
00331 
00332     NextPfn = 
MI_CONVERT_PHYSICAL_BUS_TO_PFN(*SectionOffset);
00333 
00334 
#ifdef FIRSTDBG
00335 
00336     
DbgPrint( 
"MM: Physsect, PagesToMap = %x  NextPfn = %x\n",
00337                    PagesToMap, NextPfn );
00338 
00339 
#endif //FIRSTDBG
00340 
00341     
MI_MAKE_VALID_PTE (TempPte,
00342                        NextPfn,
00343                        ProtectionMask,
00344                        PointerPte);
00345 
00346     
if (WriteCombined == 
TRUE) {
00347         
MI_SET_PTE_WRITE_COMBINE (TempPte);
00348     }
00349 
00350     
if (TempPte.
u.Hard.Write) {
00351             TempPte.
u.Hard.Dirty = 1;
00352     }
00353     
00354     
while (PointerPte <= LastPte) {
00355 
00356         ULONG PagesTogether;
00357         ULONG GranularityHint;
00358 
00359         
00360         
00361         
00362 
00363         
if (AllocationType & MEM_LARGE_PAGES) {
00364             PagesTogether = 
AggregatePages (PointerPte,
00365                                             NextPfn,
00366                                             PagesToMap,
00367                                             &GranularityHint);
00368         } 
else {
00369             PagesTogether = 1;
00370             GranularityHint = 0;
00371         }
00372 
00373 
#ifdef FIRSTDBG
00374 
00375         
DbgPrint( 
"MM: Physsect  PointerPte = %x, NextPfn = %x\n",
00376                        PointerPte, NextPfn );
00377         
DbgPrint( 
"MM: Va = %x  TempPte.Pfn = %x\n",
00378                        
MiGetVirtualAddressMappedByPte( PointerPte ),
00379                        TempPte.
u.Hard.PageFrameNumber );
00380         
DbgPrint( 
"MM: PagesToMap = %x\n", PagesToMap );
00381         
DbgPrint( 
"MM: PagesTogether = %x, GH = %x\n",
00382                        PagesTogether, GranularityHint );
00383 
00384 
#endif //FIRSTDBG
00385 
00386         TempPte.
u.Hard.GranularityHint = GranularityHint;
00387 
00388         NextPfn += PagesTogether;
00389         PagesToMap -= PagesTogether;
00390 
00391         UsedPageTableHandle = 
MI_GET_USED_PTES_HANDLE (MiGetVirtualAddressMappedByPte (PointerPte));
00392 
00393         
while (PagesTogether--) {
00394 
00395             
if (
MiIsPteOnPdeBoundary (PointerPte)) {
00396 
00397                 PointerPde = 
MiGetPteAddress (PointerPte);
00398 
00399                 
if (
MiIsPteOnPpeBoundary (PointerPte)) {
00400                     PointerPpe = 
MiGetPteAddress (PointerPde);
00401                     
MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE);
00402                     
if (PointerPde->
u.Long == 0) {
00403                         UsedPageDirectoryHandle = 
MI_GET_USED_PTES_HANDLE (PointerPte);
00404                         
ASSERT (MI_GET_USED_PTES_FROM_HANDLE (UsedPageDirectoryHandle) == 0); 
00405                 
00406                         
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
00407                     }
00408                 }
00409 
00410                 
MiMakePdeExistAndMakeValid (PointerPde, Process, FALSE);
00411                 Pfn2 = 
MI_PFN_ELEMENT (PointerPde->
u.Hard.PageFrameNumber);
00412                 UsedPageTableHandle = 
MI_GET_USED_PTES_HANDLE (MiGetVirtualAddressMappedByPte (PointerPte));
00413             }
00414 
00415             
ASSERT( PointerPte->
u.Long == 0 );
00416 
00417             *PointerPte = TempPte;
00418 
#if PFN_CONSISTENCY
00419 
            LOCK_PFN (OldIrql);
00420 
#endif
00421 
            Pfn2->
u2.ShareCount += 1;
00422 
#if PFN_CONSISTENCY
00423 
            UNLOCK_PFN (OldIrql);
00424 
#endif
00425 
00426             
00427             
00428             
00429             
00430 
00431             
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageTableHandle);
00432 
00433             PointerPte += 1;
00434 
00435             TempPte.
u.Hard.PageFrameNumber += 1;
00436 
00437         } 
00438 
00439     }  
00440 
00441     
UNLOCK_WS_UNSAFE (Process);
00442     *ReleasedWsMutex = 
TRUE;
00443 
00444     
00445     
00446     
00447 
00448     *CapturedViewSize = (ULONG)EndingAddress - (ULONG)StartingAddress + 1
L;
00449     Process->VirtualSize += *CapturedViewSize;
00450 
00451     
if (Process->VirtualSize > Process->PeakVirtualSize) {
00452         Process->PeakVirtualSize = Process->VirtualSize;
00453     }
00454 
00455     
00456     
00457     
00458     
00459     
00460     
00461     
00462     
00463     
00464 
00465     *CapturedBase = HalCreateQva( *SectionOffset, StartingAddress );
00466 
00467     
return STATUS_SUCCESS;
00468 }