Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstubs.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/arm/stubs.c 00005 * PURPOSE: ARM Memory Manager 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 ULONG MmGlobalKernelPageDirectory[1024]; 00018 MMPTE MiArmTemplatePte; 00019 MMPDE_HARDWARE MiArmTemplatePde; 00020 00021 /* PRIVATE FUNCTIONS **********************************************************/ 00022 00023 BOOLEAN 00024 NTAPI 00025 MiUnmapPageTable(IN PMMPTE PointerPde) 00026 { 00027 // 00028 // Check if this address belongs to the kernel 00029 // 00030 if (((ULONG_PTR)PointerPde > PDE_BASE) || 00031 ((ULONG_PTR)PointerPde < (PDE_BASE + 1024*1024))) 00032 { 00033 // 00034 // Nothing to do 00035 // 00036 return TRUE; 00037 } 00038 00039 // 00040 // FIXME-USER: Shouldn't get here yet 00041 // 00042 ASSERT(FALSE); 00043 return FALSE; 00044 } 00045 00046 VOID 00047 NTAPI 00048 MiFlushTlb(IN PMMPTE PointerPte, 00049 IN PVOID Address) 00050 { 00051 // 00052 // Make sure the PTE is valid, and unmap the pagetable if user-mode 00053 // 00054 if (((PointerPte) && (MiUnmapPageTable(PointerPte))) || 00055 (Address >= MmSystemRangeStart)) 00056 { 00057 // 00058 // Invalidate this page 00059 // 00060 KeArmInvalidateTlbEntry(Address); 00061 } 00062 } 00063 00064 PMMPTE 00065 NTAPI 00066 MiGetPageTableForProcess(IN PEPROCESS Process, 00067 IN PVOID Address, 00068 IN BOOLEAN Create) 00069 { 00070 //ULONG PdeOffset; 00071 PMMPTE PointerPte; 00072 PMMPDE_HARDWARE PointerPde; 00073 MMPDE_HARDWARE TempPde; 00074 MMPTE TempPte; 00075 NTSTATUS Status; 00076 PFN_NUMBER Pfn; 00077 00078 // 00079 // Check if this is a user-mode, non-kernel or non-current address 00080 // 00081 if ((Address < MmSystemRangeStart) && 00082 (Process) && 00083 (Process != PsGetCurrentProcess())) 00084 { 00085 // 00086 // FIXME-USER: No user-mode memory support 00087 // 00088 ASSERT(FALSE); 00089 } 00090 00091 // 00092 // Get our templates 00093 // 00094 TempPde = MiArmTemplatePde; 00095 TempPte = MiArmTemplatePte; 00096 00097 // 00098 // Get the PDE 00099 // 00100 PointerPde = MiGetPdeAddress(Address); 00101 if (PointerPde->u.Hard.Coarse.Valid) 00102 { 00103 // 00104 // Invalid PDE, is this a kernel address? 00105 // 00106 if (Address >= MmSystemRangeStart) 00107 { 00108 // 00109 // Does it exist in the kernel page directory? 00110 // 00111 //PdeOffset = MiGetPdeOffset(Address); 00112 //if (MmGlobalKernelPageDirectory[PdeOffset] == 0) 00113 { 00114 // 00115 // It doesn't. Is this a create operation? If not, fail 00116 // 00117 if (Create == FALSE) return NULL; 00118 kernelHack: 00119 DPRINT1("Must create a page for: %p PDE: %p\n", // Offset: %lx!\n", 00120 Address, PointerPde);//, PdeOffset); 00121 00122 // 00123 // Allocate a non paged pool page for the PDE 00124 // 00125 Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn); 00126 if (!NT_SUCCESS(Status)) return NULL; 00127 00128 // 00129 // Setup the PFN 00130 // 00131 TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn << PAGE_SHIFT) >> CPT_SHIFT; 00132 00133 // 00134 // Write the PDE 00135 // 00136 ASSERT(PointerPde->u.Hard.Coarse.Valid == 0); 00137 ASSERT(TempPde.u.Hard.Coarse.Valid == 1); 00138 *PointerPde = TempPde; 00139 00140 // 00141 // Save it 00142 // 00143 //MmGlobalKernelPageDirectory[PdeOffset] = TempPde.u.Hard.AsUlong; 00144 //DPRINT1("KPD: %p PDEADDR: %p\n", &MmGlobalKernelPageDirectory[PdeOffset], MiGetPdeAddress(Address)); 00145 00146 // 00147 // FIXFIX: Double check with Felix tomorrow 00148 // 00150 // 00151 // Get the PTE for this 1MB region 00152 // 00153 PointerPte = MiGetPteAddress(MiGetPteAddress(Address)); 00154 DPRINT1("PointerPte: %p\n", PointerPte); 00155 00156 // 00157 // Write the PFN of the PDE 00158 // 00159 TempPte.u.Hard.PageFrameNumber = Pfn; 00160 00161 // 00162 // Write the PTE 00163 // 00164 ASSERT(PointerPte->u.Hard.Valid == 0); 00165 ASSERT(TempPte.u.Hard.Valid == 1); 00166 *PointerPte = TempPte; 00168 } 00169 00170 // 00171 // Now set the actual PDE 00172 // 00173 //PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset]; 00174 } 00175 else 00176 { 00177 // 00178 // Is this a create operation? If not, fail 00179 // 00180 if (Create == FALSE) return NULL; 00181 00182 // 00183 // THIS WHOLE PATH IS TODO 00184 // 00185 goto kernelHack; 00186 ASSERT(FALSE); 00187 00188 // 00189 // Allocate a non paged pool page for the PDE 00190 // 00191 Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn); 00192 if (!NT_SUCCESS(Status)) return NULL; 00193 00194 // 00195 // Make the entry valid 00196 // 00197 TempPde.u.Hard.AsUlong = 0xDEADBEEF; 00198 00199 // 00200 // Set it 00201 // 00202 *PointerPde = TempPde; 00203 } 00204 } 00205 00206 // 00207 // Return the PTE 00208 // 00209 return MiGetPteAddress(Address); 00210 } 00211 00212 MMPTE 00213 NTAPI 00214 MiGetPageEntryForProcess(IN PEPROCESS Process, 00215 IN PVOID Address) 00216 { 00217 PMMPTE PointerPte; 00218 MMPTE Pte; 00219 Pte.u.Hard.AsUlong = 0; 00220 00221 // 00222 // Get the PTE 00223 // 00224 PointerPte = MiGetPageTableForProcess(Process, Address, FALSE); 00225 if (PointerPte) 00226 { 00227 // 00228 // Capture the PTE value and unmap the page table 00229 // 00230 Pte = *PointerPte; 00231 MiUnmapPageTable(PointerPte); 00232 } 00233 00234 // 00235 // Return the PTE value 00236 // 00237 return Pte; 00238 } 00239 00240 VOID 00241 NTAPI 00242 MmDeletePageTable(IN PEPROCESS Process, 00243 IN PVOID Address) 00244 { 00245 PMMPDE_HARDWARE PointerPde; 00246 00247 // 00248 // Not valid for kernel addresses 00249 // 00250 DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address); 00251 ASSERT(Address < MmSystemRangeStart); 00252 00253 // 00254 // Check if this is for a different process 00255 // 00256 if ((Process) && (Process != PsGetCurrentProcess())) 00257 { 00258 // 00259 // FIXME-USER: Need to attach to the process 00260 // 00261 ASSERT(FALSE); 00262 } 00263 00264 // 00265 // Get the PDE 00266 // 00267 PointerPde = MiGetPdeAddress(Address); 00268 00269 // 00270 // On ARM, we use a section mapping for the original low-memory mapping 00271 // 00272 if ((Address) || (PointerPde->u.Hard.Section.Valid == 0)) 00273 { 00274 // 00275 // Make sure it's valid 00276 // 00277 ASSERT(PointerPde->u.Hard.Coarse.Valid == 1); 00278 } 00279 00280 // 00281 // Clear the PDE 00282 // 00283 PointerPde->u.Hard.AsUlong = 0; 00284 ASSERT(PointerPde->u.Hard.Coarse.Valid == 0); 00285 00286 // 00287 // Invalidate the TLB entry 00288 // 00289 MiFlushTlb((PMMPTE)PointerPde, MiGetPteAddress(Address)); 00290 } 00291 00292 BOOLEAN 00293 NTAPI 00294 MmCreateProcessAddressSpace(IN ULONG MinWs, 00295 IN PEPROCESS Process, 00296 IN PULONG DirectoryTableBase) 00297 { 00298 NTSTATUS Status; 00299 ULONG i; 00300 PFN_NUMBER Pfn[2]; 00301 PMMPDE_HARDWARE PageDirectory, PointerPde; 00302 MMPDE_HARDWARE TempPde; 00303 ASSERT(FALSE); 00304 00305 // 00306 // Loop two tables (Hyperspace and TTB). Each one is 16KB 00307 // 00308 // 00309 for (i = 0; i < sizeof(Pfn) / sizeof(Pfn[0]); i++) 00310 { 00311 // 00312 // Allocate a page 00313 // 00314 Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]); 00315 if (!NT_SUCCESS(Status)) ASSERT(FALSE); 00316 } 00317 00318 // 00319 // Map the base 00320 // 00321 PageDirectory = MmCreateHyperspaceMapping(Pfn[0]); 00322 00323 // 00324 // Copy the PDEs for kernel-mode 00325 // 00326 RtlCopyMemory(PageDirectory + MiGetPdeOffset(MmSystemRangeStart), 00327 MmGlobalKernelPageDirectory + MiGetPdeOffset(MmSystemRangeStart), 00328 (1024 - MiGetPdeOffset(MmSystemRangeStart)) * sizeof(ULONG)); 00329 00330 00331 // 00332 // Setup the PDE for the table base 00333 // 00334 TempPde = MiArmTemplatePde; 00335 TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn[0] << PAGE_SHIFT) >> CPT_SHIFT; 00336 PointerPde = &PageDirectory[MiGetPdeOffset(PTE_BASE)]; 00337 00338 // 00339 // Write the PDE 00340 // 00341 ASSERT(PointerPde->u.Hard.Coarse.Valid == 0); 00342 ASSERT(TempPde.u.Hard.Coarse.Valid == 1); 00343 *PointerPde = TempPde; 00344 00345 // 00346 // Setup the PDE for the hyperspace 00347 // 00348 TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn[1] << PAGE_SHIFT) >> CPT_SHIFT; 00349 PointerPde = &PageDirectory[MiGetPdeOffset(HYPER_SPACE)]; 00350 00351 // 00352 // Write the PDE 00353 // 00354 ASSERT(PointerPde->u.Hard.Coarse.Valid == 0); 00355 ASSERT(TempPde.u.Hard.Coarse.Valid == 1); 00356 *PointerPde = TempPde; 00357 00358 // 00359 // Unmap the page directory 00360 // 00361 MmDeleteHyperspaceMapping(PageDirectory); 00362 00363 // 00364 // Return the page table base 00365 // 00366 DirectoryTableBase[0] = Pfn[0] << PAGE_SHIFT; 00367 return TRUE; 00368 } 00369 00370 NTSTATUS 00371 NTAPI 00372 Mmi386ReleaseMmInfo(IN PEPROCESS Process) 00373 { 00374 // 00375 // FIXME-USER: Need to delete address space 00376 // 00377 UNIMPLEMENTED; 00378 while (TRUE); 00379 return 0; 00380 } 00381 00382 PULONG 00383 NTAPI 00384 MmGetPageDirectory(VOID) 00385 { 00386 // 00387 // Return the TTB 00388 // 00389 return (PULONG)KeArmTranslationTableRegisterGet().AsUlong; 00390 } 00391 00392 VOID 00393 NTAPI 00394 MmDisableVirtualMapping(IN PEPROCESS Process, 00395 IN PVOID Address, 00396 OUT PBOOLEAN WasDirty, 00397 OUT PPFN_NUMBER Page) 00398 { 00399 // 00400 // TODO 00401 // 00402 UNIMPLEMENTED; 00403 while (TRUE); 00404 } 00405 00406 VOID 00407 NTAPI 00408 MmEnableVirtualMapping(IN PEPROCESS Process, 00409 IN PVOID Address) 00410 { 00411 // 00412 // TODO 00413 // 00414 UNIMPLEMENTED; 00415 while (TRUE); 00416 } 00417 00418 NTSTATUS 00419 NTAPI 00420 MmCreateVirtualMappingInternal(IN PEPROCESS Process, 00421 IN PVOID Address, 00422 IN ULONG Protection, 00423 IN PPFN_NUMBER Pages, 00424 IN ULONG PageCount, 00425 IN BOOLEAN MarkAsMapped) 00426 { 00427 PMMPTE PointerPte = NULL; 00428 MMPTE TempPte; 00429 PVOID Addr; 00430 ULONG OldPdeOffset, PdeOffset, i; 00431 DPRINT("[KMAP]: %p %d\n", Address, PageCount); 00432 //ASSERT(Address >= MmSystemRangeStart); 00433 00434 // 00435 // Get our template PTE 00436 // 00437 TempPte = MiArmTemplatePte; 00438 00439 // 00440 // Loop every page 00441 // 00442 Addr = Address; 00443 OldPdeOffset = MiGetPdeOffset(Addr) + 1; 00444 for (i = 0; i < PageCount; i++) 00445 { 00446 // 00447 // Get the next PDE offset and check if it's a new one 00448 // 00449 PdeOffset = MiGetPdeOffset(Addr); 00450 if (OldPdeOffset != PdeOffset) 00451 { 00452 // 00453 // Get rid of the old L2 Table, if this was the last PTE on it 00454 // 00455 MiUnmapPageTable(PointerPte); 00456 00457 // 00458 // Get the PTE for this address, and create the PDE for it 00459 // 00460 PointerPte = MiGetPageTableForProcess(NULL, Addr, TRUE); 00461 ASSERT(PointerPte); 00462 } 00463 else 00464 { 00465 // 00466 // Go to the next PTE on this PDE 00467 // 00468 ASSERT(PointerPte); 00469 PointerPte++; 00470 } 00471 00472 // 00473 // Save the current PDE 00474 // 00475 OldPdeOffset = PdeOffset; 00476 00477 // 00478 // Set the PFN 00479 // 00480 TempPte.u.Hard.PageFrameNumber = *Pages++; 00481 00482 // 00483 // Write the PTE 00484 // 00485 ASSERT(PointerPte->u.Hard.Valid == 0); 00486 ASSERT(TempPte.u.Hard.Valid == 1); 00487 *PointerPte = TempPte; 00488 00489 // 00490 // Move to the next page 00491 // 00492 Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE); 00493 } 00494 00495 // 00496 // All done 00497 // 00498 return STATUS_SUCCESS; 00499 } 00500 00501 NTSTATUS 00502 NTAPI 00503 MmCreateVirtualMappingForKernel(IN PVOID Address, 00504 IN ULONG Protection, 00505 IN PPFN_NUMBER Pages, 00506 IN ULONG PageCount) 00507 { 00508 // 00509 // Call the internal version 00510 // 00511 return MmCreateVirtualMappingInternal(NULL, 00512 Address, 00513 Protection, 00514 Pages, 00515 PageCount, 00516 FALSE); 00517 } 00518 00519 NTSTATUS 00520 NTAPI 00521 MmCreateVirtualMappingUnsafe(IN PEPROCESS Process, 00522 IN PVOID Address, 00523 IN ULONG Protection, 00524 IN PPFN_NUMBER Pages, 00525 IN ULONG PageCount) 00526 { 00527 // 00528 // Are we only handling the kernel? 00529 // 00530 if (!(Process) || (Process == PsGetCurrentProcess())) 00531 { 00532 // 00533 // Call the internal version 00534 // 00535 return MmCreateVirtualMappingInternal(Process, 00536 Address, 00537 Protection, 00538 Pages, 00539 PageCount, 00540 TRUE); 00541 } 00542 00543 // 00544 // FIXME-USER: Support user-mode mappings 00545 // 00546 ASSERT(FALSE); 00547 return 0; 00548 } 00549 00550 NTSTATUS 00551 NTAPI 00552 MmCreateVirtualMapping(IN PEPROCESS Process, 00553 IN PVOID Address, 00554 IN ULONG Protection, 00555 IN PPFN_NUMBER Pages, 00556 IN ULONG PageCount) 00557 { 00558 ULONG i; 00559 00560 // 00561 // Loop each page 00562 // 00563 for (i = 0; i < PageCount; i++) 00564 { 00565 // 00566 // Make sure the page is marked as in use 00567 // 00568 ASSERT(MmIsPageInUse(Pages[i])); 00569 } 00570 00571 // 00572 // Call the unsafe version 00573 // 00574 return MmCreateVirtualMappingUnsafe(Process, 00575 Address, 00576 Protection, 00577 Pages, 00578 PageCount); 00579 } 00580 00581 VOID 00582 NTAPI 00583 MmRawDeleteVirtualMapping(IN PVOID Address) 00584 { 00585 PMMPTE PointerPte; 00586 00587 // 00588 // Get the PTE 00589 // 00590 PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE); 00591 if ((PointerPte) && (PointerPte->u.Hard.Valid)) 00592 { 00593 // 00594 // Destroy it 00595 // 00596 PointerPte->u.Hard.AsUlong = 0; 00597 00598 // 00599 // Flush the TLB 00600 // 00601 MiFlushTlb(PointerPte, Address); 00602 } 00603 } 00604 00605 VOID 00606 NTAPI 00607 MmDeleteVirtualMapping(IN PEPROCESS Process, 00608 IN PVOID Address, 00609 IN BOOLEAN FreePage, 00610 OUT PBOOLEAN WasDirty, 00611 OUT PPFN_NUMBER Page) 00612 { 00613 PMMPTE PointerPte; 00614 MMPTE Pte; 00615 PFN_NUMBER Pfn = 0; 00616 00617 // 00618 // Get the PTE 00619 // 00620 PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE); 00621 if (PointerPte) 00622 { 00623 // 00624 // Save and destroy the PTE 00625 // 00626 Pte = *PointerPte; 00627 PointerPte->u.Hard.AsUlong = 0; 00628 00629 // 00630 // Flush the TLB 00631 // 00632 MiFlushTlb(PointerPte, Address); 00633 00634 // 00635 // Unmap the PFN 00636 // 00637 Pfn = Pte.u.Hard.PageFrameNumber; 00638 00639 // 00640 // Release the PFN if it was ours 00641 // 00642 if ((FreePage) && (Pfn)) MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); 00643 } 00644 00645 // 00646 // Return if the page was dirty 00647 // 00648 if (WasDirty) *WasDirty = FALSE; // LIE!!! 00649 if (Page) *Page = Pfn; 00650 } 00651 00652 VOID 00653 NTAPI 00654 MmDeletePageFileMapping(IN PEPROCESS Process, 00655 IN PVOID Address, 00656 IN SWAPENTRY *SwapEntry) 00657 { 00658 // 00659 // TODO 00660 // 00661 UNIMPLEMENTED; 00662 while (TRUE); 00663 } 00664 00665 NTSTATUS 00666 NTAPI 00667 MmCreatePageFileMapping(IN PEPROCESS Process, 00668 IN PVOID Address, 00669 IN SWAPENTRY SwapEntry) 00670 { 00671 // 00672 // TODO 00673 // 00674 UNIMPLEMENTED; 00675 while (TRUE); 00676 return 0; 00677 } 00678 00679 PFN_NUMBER 00680 NTAPI 00681 MmGetPfnForProcess(IN PEPROCESS Process, 00682 IN PVOID Address) 00683 { 00684 MMPTE Pte; 00685 00686 // 00687 // Get the PTE 00688 // 00689 Pte = MiGetPageEntryForProcess(Process, Address); 00690 if (Pte.u.Hard.Valid == 0) return 0; 00691 00692 // 00693 // Return PFN 00694 // 00695 return Pte.u.Hard.PageFrameNumber; 00696 } 00697 00698 BOOLEAN 00699 NTAPI 00700 MmIsDirtyPage(IN PEPROCESS Process, 00701 IN PVOID Address) 00702 { 00703 // 00704 // TODO 00705 // 00706 UNIMPLEMENTED; 00707 while (TRUE); 00708 return 0; 00709 } 00710 00711 VOID 00712 NTAPI 00713 MmSetCleanPage(IN PEPROCESS Process, 00714 IN PVOID Address) 00715 { 00716 // 00717 // TODO 00718 // 00719 UNIMPLEMENTED; 00720 while (TRUE); 00721 } 00722 00723 VOID 00724 NTAPI 00725 MmSetDirtyPage(IN PEPROCESS Process, 00726 IN PVOID Address) 00727 { 00728 // 00729 // TODO 00730 // 00731 UNIMPLEMENTED; 00732 while (TRUE); 00733 } 00734 00735 BOOLEAN 00736 NTAPI 00737 MmIsPagePresent(IN PEPROCESS Process, 00738 IN PVOID Address) 00739 { 00740 // 00741 // Fault PTEs are 0, which is FALSE (non-present) 00742 // 00743 return MiGetPageEntryForProcess(Process, Address).u.Hard.Valid; 00744 } 00745 00746 BOOLEAN 00747 NTAPI 00748 MmIsPageSwapEntry(IN PEPROCESS Process, 00749 IN PVOID Address) 00750 { 00751 MMPTE Pte; 00752 00753 // 00754 // Get the PTE 00755 // 00756 Pte = MiGetPageEntryForProcess(Process, Address); 00757 00758 // 00759 // Make sure it exists, but is faulting 00760 // 00761 return (Pte.u.Hard.Valid == 0) && (Pte.u.Hard.AsUlong); 00762 } 00763 00764 ULONG 00765 NTAPI 00766 MmGetPageProtect(IN PEPROCESS Process, 00767 IN PVOID Address) 00768 { 00769 // 00770 // We don't enforce any protection on the pages -- they are all RWX 00771 // 00772 return PAGE_READWRITE; 00773 } 00774 00775 VOID 00776 NTAPI 00777 MmSetPageProtect(IN PEPROCESS Process, 00778 IN PVOID Address, 00779 IN ULONG Protection) 00780 { 00781 // 00782 // We don't enforce any protection on the pages -- they are all RWX 00783 // 00784 return; 00785 } 00786 00787 VOID 00788 NTAPI 00789 MmInitGlobalKernelPageDirectory(VOID) 00790 { 00791 ULONG i; 00792 PULONG CurrentPageDirectory = (PULONG)PDE_BASE; 00793 00794 // 00795 // Good place to setup template PTE/PDEs. 00796 // We are lazy and pick a known-good PTE 00797 // 00798 MiArmTemplatePte = *MiGetPteAddress(0x80000000); 00799 MiArmTemplatePde = *MiGetPdeAddress(0x80000000); 00800 00801 // 00802 // Loop the 2GB of address space which belong to the kernel 00803 // 00804 for (i = MiGetPdeOffset(MmSystemRangeStart); i < 1024; i++) 00805 { 00806 // 00807 // Check if we have an entry for this already 00808 // 00809 if ((i != MiGetPdeOffset(PTE_BASE)) && 00810 (i != MiGetPdeOffset(HYPER_SPACE)) && 00811 (!MmGlobalKernelPageDirectory[i]) && 00812 (CurrentPageDirectory[i])) 00813 { 00814 // 00815 // We don't, link it in our global page directory 00816 // 00817 MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; 00818 } 00819 } 00820 } 00821 00822 VOID 00823 NTAPI 00824 MiInitPageDirectoryMap(VOID) 00825 { 00826 MEMORY_AREA* MemoryArea = NULL; 00827 PHYSICAL_ADDRESS BoundaryAddressMultiple; 00828 PVOID BaseAddress; 00829 NTSTATUS Status; 00830 00831 // 00832 // Create memory area for the PTE area 00833 // 00834 BoundaryAddressMultiple.QuadPart = 0; 00835 BaseAddress = (PVOID)PTE_BASE; 00836 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), 00837 MEMORY_AREA_OWNED_BY_ARM3, 00838 &BaseAddress, 00839 0x1000000, 00840 PAGE_READWRITE, 00841 &MemoryArea, 00842 TRUE, 00843 0, 00844 BoundaryAddressMultiple); 00845 ASSERT(NT_SUCCESS(Status)); 00846 00847 // 00848 // Create memory area for the PDE area 00849 // 00850 BaseAddress = (PVOID)PDE_BASE; 00851 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), 00852 MEMORY_AREA_OWNED_BY_ARM3, 00853 &BaseAddress, 00854 0x100000, 00855 PAGE_READWRITE, 00856 &MemoryArea, 00857 TRUE, 00858 0, 00859 BoundaryAddressMultiple); 00860 ASSERT(NT_SUCCESS(Status)); 00861 00862 // 00863 // And finally, hyperspace 00864 // 00865 BaseAddress = (PVOID)HYPER_SPACE; 00866 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), 00867 MEMORY_AREA_OWNED_BY_ARM3, 00868 &BaseAddress, 00869 PAGE_SIZE, 00870 PAGE_READWRITE, 00871 &MemoryArea, 00872 TRUE, 00873 0, 00874 BoundaryAddressMultiple); 00875 ASSERT(NT_SUCCESS(Status)); 00876 } 00877 00878 /* PUBLIC FUNCTIONS ***********************************************************/ 00879 00880 /* 00881 * @implemented 00882 */ 00883 PHYSICAL_ADDRESS 00884 NTAPI 00885 MmGetPhysicalAddress(IN PVOID Address) 00886 { 00887 PHYSICAL_ADDRESS PhysicalAddress; 00888 MMPTE Pte; 00889 00890 // 00891 // Early boot PCR check 00892 // 00893 if (Address == PCR) 00894 { 00895 // 00896 // ARM Hack while we still use a section PTE 00897 // 00898 PMMPDE_HARDWARE PointerPde; 00899 PointerPde = MiGetPdeAddress(PCR); 00900 ASSERT(PointerPde->u.Hard.Section.Valid == 1); 00901 PhysicalAddress.QuadPart = PointerPde->u.Hard.Section.PageFrameNumber; 00902 PhysicalAddress.QuadPart <<= CPT_SHIFT; 00903 PhysicalAddress.LowPart += BYTE_OFFSET(Address); 00904 return PhysicalAddress; 00905 } 00906 00907 // 00908 // Get the PTE 00909 // 00910 Pte = MiGetPageEntryForProcess(NULL, Address); 00911 if (Pte.u.Hard.Valid) 00912 { 00913 // 00914 // Return the information 00915 // 00916 PhysicalAddress.QuadPart = Pte.u.Hard.PageFrameNumber; 00917 PhysicalAddress.QuadPart <<= PAGE_SHIFT; 00918 PhysicalAddress.LowPart += BYTE_OFFSET(Address); 00919 } 00920 else 00921 { 00922 // 00923 // Invalid or unmapped 00924 // 00925 PhysicalAddress.QuadPart = 0; 00926 } 00927 00928 // 00929 // Return the physical address 00930 // 00931 return PhysicalAddress; 00932 } Generated on Sun May 27 2012 04:21:46 for ReactOS by
1.7.6.1
|