Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

physsect.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

ULONG MaximumAlignment (ULONG Offset)
ULONG AggregatePages (PMMPTE, PFN_NUMBER, ULONG, PULONG)
NTSTATUS MiMapViewOfPhysicalSection (IN PCONTROL_AREA ControlArea, IN PEPROCESS Process, IN PVOID *CapturedBase, IN PLARGE_INTEGER SectionOffset, IN PSIZE_T CapturedViewSize, IN ULONG ProtectionMask, IN ULONG_PTR ZeroBits, IN ULONG AllocationType, IN BOOLEAN WriteCombined, OUT PBOOLEAN ReleasedWsMutex)
ULONG MaximumAlignment (IN ULONG Offset)
ULONG AggregatePages (IN PMMPTE PointerPte, IN PFN_NUMBER Pfn, IN ULONG Pages, OUT PULONG GranularityHint)


Function Documentation

ULONG AggregatePages IN PMMPTE  PointerPte,
IN PFN_NUMBER  Pfn,
IN ULONG  Pages,
OUT PULONG  GranularityHint
 

Definition at line 522 of file axp64/physsect.c.

References DbgPrint, GH0, GH1, GH1_PAGE_SIZE, GH2, GH2_PAGE_SIZE, GH3, GH3_PAGE_SIZE, MaximumAlignment(), MiGetVirtualAddressMappedByPte, PAGE_SHIFT, and PAGE_SIZE.

Referenced by MiMapViewOfPhysicalSection().

00530 : 00531 00532 This routine computes the number of standard size pages that can be 00533 aggregated into a single large page and returns the granularity hint 00534 for that size large page. 00535 00536 Arguments: 00537 00538 PointerPte - Supplies the PTE pointer for the starting virtual address 00539 of the mapping. 00540 Pfn - Supplies the starting page frame number of the memory to be 00541 mapped. 00542 Pages - Supplies the number of pages to map. 00543 00544 GranularityHint - Receives the granularity hint for the large page used 00545 to aggregate the standard pages. 00546 00547 Return Value: 00548 00549 The number of pages that can be aggregated together. 00550 00551 Environment: 00552 00553 --*/ 00554 { 00555 00556 ULONG MaxVirtualAlignment; 00557 ULONG MaxPhysicalAlignment; 00558 ULONG MaxPageAlignment; 00559 ULONG MaxAlignment; 00560 00561 // 00562 // Determine the largest page that will map a maximum of Pages. 00563 // The largest page must be both virtually and physically aligned 00564 // to the large page size boundary. 00565 // Determine the largest common alignment for the virtual and 00566 // physical addresses, factor in Pages, and then match to the 00567 // largest page size possible via the granularity hints. 00568 // 00569 00570 MaxVirtualAlignment = 00571 MaximumAlignment((ULONG)((ULONG_PTR)MiGetVirtualAddressMappedByPte(PointerPte))); 00572 00573 MaxPhysicalAlignment = MaximumAlignment( (ULONG)(Pfn << PAGE_SHIFT) ); 00574 00575 MaxPageAlignment = (ULONG)(Pages << PAGE_SHIFT); 00576 00577 #ifdef AGGREGATE_DBG 00578 00579 DbgPrint( "MM: Aggregate MaxVirtualAlign = %x\n", MaxVirtualAlignment ); 00580 DbgPrint( "MM: Aggregate MaxPhysicalAlign = %x\n", MaxPhysicalAlignment ); 00581 DbgPrint( "MM: Aggregate MaxPageAlign = %x\n", MaxPageAlignment ); 00582 00583 #endif //AGGREGATE_DBG 00584 // 00585 // Maximum alignment is the minimum of the virtual and physical alignments. 00586 // 00587 00588 MaxAlignment = (MaxVirtualAlignment > MaxPhysicalAlignment) ? 00589 MaxPhysicalAlignment : MaxVirtualAlignment; 00590 MaxAlignment = (MaxAlignment > MaxPageAlignment) ? 00591 MaxPageAlignment : MaxAlignment; 00592 00593 // 00594 // Convert MaxAlignment to granularity hint value 00595 // 00596 00597 if( (MaxAlignment & (GH3_PAGE_SIZE - 1)) == 0 ){ 00598 00599 *GranularityHint = GH3; 00600 00601 } else if( (MaxAlignment & (GH2_PAGE_SIZE - 1)) == 0 ){ 00602 00603 *GranularityHint = GH2; 00604 00605 } else if( (MaxAlignment & (GH1_PAGE_SIZE - 1)) == 0 ){ 00606 00607 *GranularityHint = GH1; 00608 00609 } else if( (MaxAlignment & (PAGE_SIZE - 1)) == 0 ){ 00610 00611 *GranularityHint = GH0; 00612 00613 } else { 00614 00615 *GranularityHint = GH0; 00616 00617 #if DBG 00618 00619 DbgPrint( "MM: Aggregate Physical pages - not page aligned\n" ); 00620 00621 #endif //DBG 00622 00623 } // end, if then elseif 00624 00625 // 00626 // Return number of pages aggregated. 00627 // 00628 00629 return( MaxAlignment >> PAGE_SHIFT ); 00630 00631 } }

ULONG AggregatePages PMMPTE  ,
PFN_NUMBER  ,
ULONG  ,
PULONG 
[static]
 

ULONG MaximumAlignment IN ULONG  Offset  ) 
 

Definition at line 478 of file axp64/physsect.c.

References GH1_PAGE_SIZE, GH2_PAGE_SIZE, GH3_PAGE_SIZE, Offset, and PAGE_SIZE.

Referenced by AggregatePages(), and MiMapViewOfPhysicalSection().

00483 : 00484 00485 This routine returns the maximum granularity hint alignment boundary 00486 to which Offset is naturally aligned. 00487 00488 Arguments: 00489 00490 Offset - Supplies the address offset to check for alignment. 00491 00492 Return Value: 00493 00494 The number which represents the largest natural alignment of Offset. 00495 00496 Environment: 00497 00498 --*/ 00499 { 00500 00501 if( (Offset & (GH3_PAGE_SIZE - 1)) == 0 ){ 00502 return GH3_PAGE_SIZE; 00503 } 00504 00505 if( (Offset & (GH2_PAGE_SIZE - 1)) == 0 ){ 00506 return GH2_PAGE_SIZE; 00507 } 00508 00509 if( (Offset & (GH1_PAGE_SIZE - 1)) == 0 ){ 00510 return GH1_PAGE_SIZE; 00511 } 00512 00513 if( (Offset & (PAGE_SIZE - 1)) == 0 ){ 00514 return PAGE_SIZE; 00515 } 00516 00517 return 0; 00518 }

ULONG MaximumAlignment ULONG  Offset  )  [static]
 

NTSTATUS MiMapViewOfPhysicalSection IN PCONTROL_AREA  ControlArea,
IN PEPROCESS  Process,
IN PVOID *  CapturedBase,
IN PLARGE_INTEGER  SectionOffset,
IN PSIZE_T  CapturedViewSize,
IN ULONG  ProtectionMask,
IN ULONG_PTR  ZeroBits,
IN ULONG  AllocationType,
IN BOOLEAN  WriteCombined,
OUT PBOOLEAN  ReleasedWsMutex
 

Definition at line 45 of file axp64/physsect.c.

References AggregatePages(), ASSERT, _MMVAD::ControlArea, DbgPrint, _MMVAD::EndingVpn, _MI_PHYSICAL_VIEW::EndVa, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseStatus(), FALSE, _MMVAD::FirstPrototypePte, L, _MMVAD::LastContiguousPte, _MI_PHYSICAL_VIEW::ListEntry, LOCK_AWE, LOCK_PFN, LOCK_PFN2, LOCK_WS, MaximumAlignment(), MI_64K_ALIGN, MI_CONVERT_PHYSICAL_BUS_TO_PFN, MI_GET_USED_PTES_FROM_HANDLE, MI_GET_USED_PTES_HANDLE, MI_INCREMENT_USED_PTES_BY_HANDLE, MI_MAKE_VALID_PTE, MI_PFN_ELEMENT, MI_PHYSICAL_VIEW_KEY, MI_SET_PTE_WRITE_COMBINE, MI_VA_TO_VPN, MiCheckForConflictingVad, MiFindEmptyAddressRange(), MiGetPdeAddress, MiGetPpeAddress, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MiInsertVad(), MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MiMakePdeExistAndMakeValid(), MiMakePpeExistAndMakeValid, NonPagedPool, NULL, PAGE_SHIFT, PAGE_SIZE, _MMVAD::StartingVpn, _MI_PHYSICAL_VIEW::StartVa, TRUE, _MMPTE::u, _MMVAD::u, _MMPFN::u2, _MMVAD::u2, _MMVAD::u4, UNLOCK_AWE, UNLOCK_PFN, UNLOCK_PFN2, UNLOCK_WS, _MI_PHYSICAL_VIEW::Vad, and X64K.

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


Generated on Sat May 15 19:45:03 2004 for test by doxygen 1.3.7