ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

memory.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS HAL
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            hal/halx86/generic/memory.c
00005  * PURPOSE:         HAL memory management
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <hal.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* Share with Mm headers? */
00016 #define MM_HAL_HEAP_START   (PVOID)(MM_HAL_VA_START + (1024 * 1024))
00017 
00018 /* GLOBALS *******************************************************************/
00019 
00020 ULONG HalpUsedAllocDescriptors;
00021 MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64];
00022 PVOID HalpHeapStart = MM_HAL_HEAP_START;
00023 
00024 
00025 /* PRIVATE FUNCTIONS *********************************************************/
00026 
00027 ULONG_PTR
00028 NTAPI
00029 HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00030                         IN ULONG_PTR MaxAddress,
00031                         IN PFN_NUMBER PageCount,
00032                         IN BOOLEAN Aligned)
00033 {
00034     ULONG UsedDescriptors;
00035     ULONG_PTR PhysicalAddress;
00036     PFN_NUMBER MaxPage, BasePage, Alignment;
00037     PLIST_ENTRY NextEntry;
00038     PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;
00039 
00040     /* Highest page we'll go */
00041     MaxPage = MaxAddress >> PAGE_SHIFT;
00042 
00043     /* We need at least two blocks */
00044     if ((HalpUsedAllocDescriptors + 2) > 64) return 0;
00045 
00046     /* Remember how many we have now */
00047     UsedDescriptors = HalpUsedAllocDescriptors;
00048 
00049     /* Loop the loader block memory descriptors */
00050     NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
00051     while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
00052     {
00053         /* Get the block */
00054         MdBlock = CONTAINING_RECORD(NextEntry,
00055                                     MEMORY_ALLOCATION_DESCRIPTOR,
00056                                     ListEntry);
00057 
00058         /* No alignment by default */
00059         Alignment = 0;
00060 
00061         /* Unless requested, in which case we use a 64KB block alignment */
00062         if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;
00063 
00064         /* Search for free memory */
00065         if ((MdBlock->MemoryType == LoaderFree) ||
00066             (MdBlock->MemoryType == LoaderFirmwareTemporary))
00067         {
00068             /* Make sure the page is within bounds, including alignment */
00069             BasePage = MdBlock->BasePage;
00070             if ((BasePage) &&
00071                 (MdBlock->PageCount >= PageCount + Alignment) &&
00072                 (BasePage + PageCount + Alignment < MaxPage))
00073             {
00074 
00075                 /* We found an address */
00076                 PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT;
00077                 break;
00078             }
00079         }
00080 
00081         /* Keep trying */
00082         NextEntry = NextEntry->Flink;
00083     }
00084 
00085     /* If we didn't find anything, get out of here */
00086     if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;
00087 
00088     /* Okay, now get a descriptor */
00089     NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors];
00090     NewBlock->PageCount = (ULONG)PageCount;
00091     NewBlock->BasePage = MdBlock->BasePage + Alignment;
00092     NewBlock->MemoryType = LoaderHALCachedMemory;
00093 
00094     /* Update count */
00095     UsedDescriptors++;
00096     HalpUsedAllocDescriptors = UsedDescriptors;
00097 
00098     /* Check if we had any alignment */
00099     if (Alignment)
00100     {
00101         /* Check if we had leftovers */
00102         if (MdBlock->PageCount > (PageCount + Alignment))
00103         {
00104             /* Get the next descriptor */
00105             FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
00106             FreeBlock->PageCount = MdBlock->PageCount - Alignment - (ULONG)PageCount;
00107             FreeBlock->BasePage = MdBlock->BasePage + Alignment + (ULONG)PageCount;
00108 
00109             /* One more */
00110             HalpUsedAllocDescriptors++;
00111 
00112             /* Insert it into the list */
00113             InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
00114         }
00115 
00116         /* Trim the original block to the alignment only */
00117         MdBlock->PageCount = Alignment;
00118 
00119         /* Insert the descriptor after the original one */
00120         InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
00121     }
00122     else
00123     {
00124         /* Consume memory from this block */
00125         MdBlock->BasePage += (ULONG)PageCount;
00126         MdBlock->PageCount -= (ULONG)PageCount;
00127 
00128         /* Insert the descriptor before the original one */
00129         InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);
00130 
00131         /* Remove the entry if the whole block was allocated */
00132         if (MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
00133     }
00134 
00135     /* Return the address */
00136     return PhysicalAddress;
00137 }
00138 
00139 PVOID
00140 NTAPI
00141 HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
00142                         IN PFN_COUNT PageCount)
00143 {
00144     PHARDWARE_PTE PointerPte;
00145     PFN_NUMBER UsedPages = 0;
00146     PVOID VirtualAddress, BaseAddress;
00147 
00148     /* Start at the current HAL heap base */
00149     BaseAddress = HalpHeapStart;
00150     VirtualAddress = BaseAddress;
00151 
00152     /* Loop until we have all the pages required */
00153     while (UsedPages < PageCount)
00154     {
00155         /* If this overflows past the HAL heap, it means there's no space */
00156         if (VirtualAddress == NULL) return NULL;
00157 
00158         /* Get the PTE for this address */
00159         PointerPte = HalAddressToPte(VirtualAddress);
00160 
00161         /* Go to the next page */
00162         VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
00163 
00164         /* Check if the page is available */
00165         if (PointerPte->Valid)
00166         {
00167             /* PTE has data, skip it and start with a new base address */
00168             BaseAddress = VirtualAddress;
00169             UsedPages = 0;
00170             continue;
00171         }
00172 
00173         /* PTE is available, keep going on this run */
00174         UsedPages++;
00175     }
00176 
00177     /* Take the base address of the page plus the actual offset in the address */
00178     VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress +
00179                              BYTE_OFFSET(PhysicalAddress.LowPart));
00180 
00181     /* If we are starting at the heap, move the heap */
00182     if (BaseAddress == HalpHeapStart)
00183     {
00184         /* Past this allocation */
00185         HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE));
00186     }
00187 
00188     /* Loop pages that can be mapped */
00189     while (UsedPages--)
00190     {
00191         /* Fill out the PTE */
00192         PointerPte = HalAddressToPte(BaseAddress);
00193         PointerPte->PageFrameNumber = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
00194         PointerPte->Valid = 1;
00195         PointerPte->Write = 1;
00196 
00197         /* Move to the next address */
00198         PhysicalAddress.QuadPart += PAGE_SIZE;
00199         BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE);
00200     }
00201 
00202     /* Flush the TLB and return the address */
00203     HalpFlushTLB();
00204     return VirtualAddress;
00205 }
00206 
00207 VOID
00208 NTAPI
00209 HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
00210                         IN PFN_COUNT PageCount)
00211 {
00212     PHARDWARE_PTE PointerPte;
00213     ULONG i;
00214 
00215     /* Only accept valid addresses */
00216     if (VirtualAddress < (PVOID)MM_HAL_VA_START) return;
00217 
00218     /* Align it down to page size */
00219     VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1));
00220 
00221     /* Loop PTEs */
00222     PointerPte = HalAddressToPte(VirtualAddress);
00223     for (i = 0; i < PageCount; i++)
00224     {
00225         *(PULONG)PointerPte = 0;
00226         PointerPte++;
00227     }
00228 
00229     /* Flush the TLB */
00230     HalpFlushTLB();
00231 
00232     /* Put the heap back */
00233     if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress;
00234 }
00235 

Generated on Sun May 27 2012 04:18:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.