mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[HAL]
- Move memory functions from halinit.c to new memory.c - HalpAllocPhysicalMemory: MemoryFirmwareTemporary -> LoaderFirmwareTemporary (same value, different enum) svn path=/trunk/; revision=47563
This commit is contained in:
parent
0d06145871
commit
32f5fc6eab
3 changed files with 237 additions and 215 deletions
|
@ -14,223 +14,10 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* Share with Mm headers? */
|
||||
#define MM_HAL_VA_START (PVOID)0xFFC00000
|
||||
#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024))
|
||||
|
||||
BOOLEAN HalpPciLockSettings;
|
||||
ULONG HalpUsedAllocDescriptors;
|
||||
MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64];
|
||||
PVOID HalpHeapStart = MM_HAL_HEAP_START;
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN ULONG MaxAddress,
|
||||
IN ULONG PageCount,
|
||||
IN BOOLEAN Aligned)
|
||||
{
|
||||
ULONG UsedDescriptors, Alignment, PhysicalAddress;
|
||||
PFN_NUMBER MaxPage, BasePage;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;
|
||||
|
||||
/* Highest page we'll go */
|
||||
MaxPage = MaxAddress >> PAGE_SHIFT;
|
||||
|
||||
/* We need at least two blocks */
|
||||
if ((HalpUsedAllocDescriptors + 2) > 64) return 0;
|
||||
|
||||
/* Remember how many we have now */
|
||||
UsedDescriptors = HalpUsedAllocDescriptors;
|
||||
|
||||
/* Loop the loader block memory descriptors */
|
||||
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||||
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
|
||||
{
|
||||
/* Get the block */
|
||||
MdBlock = CONTAINING_RECORD(NextEntry,
|
||||
MEMORY_ALLOCATION_DESCRIPTOR,
|
||||
ListEntry);
|
||||
|
||||
/* No alignment by default */
|
||||
Alignment = 0;
|
||||
|
||||
/* Unless requested, in which case we use a 64KB block alignment */
|
||||
if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;
|
||||
|
||||
/* Search for free memory */
|
||||
if ((MdBlock->MemoryType == LoaderFree) ||
|
||||
(MdBlock->MemoryType == MemoryFirmwareTemporary))
|
||||
{
|
||||
/* Make sure the page is within bounds, including alignment */
|
||||
BasePage = MdBlock->BasePage;
|
||||
if ((BasePage) &&
|
||||
(MdBlock->PageCount >= PageCount + Alignment) &&
|
||||
(BasePage + PageCount + Alignment < MaxPage))
|
||||
{
|
||||
|
||||
/* We found an address */
|
||||
PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep trying */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* If we didn't find anything, get out of here */
|
||||
if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;
|
||||
|
||||
/* Okay, now get a descriptor */
|
||||
NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors];
|
||||
NewBlock->PageCount = PageCount;
|
||||
NewBlock->BasePage = MdBlock->BasePage + Alignment;
|
||||
NewBlock->MemoryType = LoaderHALCachedMemory;
|
||||
|
||||
/* Update count */
|
||||
UsedDescriptors++;
|
||||
HalpUsedAllocDescriptors = UsedDescriptors;
|
||||
|
||||
/* Check if we had any alignment */
|
||||
if (Alignment)
|
||||
{
|
||||
/* Check if we had leftovers */
|
||||
if ((MdBlock->PageCount - Alignment) != PageCount)
|
||||
{
|
||||
/* Get the next descriptor */
|
||||
FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
|
||||
FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount;
|
||||
FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount;
|
||||
|
||||
/* One more */
|
||||
HalpUsedAllocDescriptors++;
|
||||
|
||||
/* Insert it into the list */
|
||||
InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
|
||||
}
|
||||
|
||||
/* Use this descriptor */
|
||||
NewBlock->PageCount = Alignment;
|
||||
InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Consume memory from this block */
|
||||
MdBlock->BasePage += PageCount;
|
||||
MdBlock->PageCount -= PageCount;
|
||||
|
||||
/* Insert the descriptor */
|
||||
InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);
|
||||
|
||||
/* Remove the entry if the whole block was allocated */
|
||||
if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
|
||||
}
|
||||
|
||||
/* Return the address */
|
||||
return PhysicalAddress;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
PHARDWARE_PTE PointerPte;
|
||||
ULONG UsedPages = 0;
|
||||
PVOID VirtualAddress, BaseAddress;
|
||||
|
||||
/* Start at the current HAL heap base */
|
||||
BaseAddress = HalpHeapStart;
|
||||
VirtualAddress = BaseAddress;
|
||||
|
||||
/* Loop until we have all the pages required */
|
||||
while (UsedPages < PageCount)
|
||||
{
|
||||
/* If this overflows past the HAL heap, it means there's no space */
|
||||
if (VirtualAddress == NULL) return NULL;
|
||||
|
||||
/* Get the PTE for this address */
|
||||
PointerPte = HalAddressToPte(VirtualAddress);
|
||||
|
||||
/* Go to the next page */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
|
||||
|
||||
/* Check if the page is available */
|
||||
if (PointerPte->Valid)
|
||||
{
|
||||
/* PTE has data, skip it and start with a new base address */
|
||||
BaseAddress = VirtualAddress;
|
||||
UsedPages = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* PTE is available, keep going on this run */
|
||||
UsedPages++;
|
||||
}
|
||||
|
||||
/* Take the base address of the page plus the actual offset in the address */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress +
|
||||
BYTE_OFFSET(PhysicalAddress.LowPart));
|
||||
|
||||
/* If we are starting at the heap, move the heap */
|
||||
if (BaseAddress == HalpHeapStart)
|
||||
{
|
||||
/* Past this allocation */
|
||||
HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE));
|
||||
}
|
||||
|
||||
/* Loop pages that can be mapped */
|
||||
while (UsedPages--)
|
||||
{
|
||||
/* Fill out the PTE */
|
||||
PointerPte = HalAddressToPte(BaseAddress);
|
||||
PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT;
|
||||
PointerPte->Valid = 1;
|
||||
PointerPte->Write = 1;
|
||||
|
||||
/* Move to the next address */
|
||||
PhysicalAddress.QuadPart += PAGE_SIZE;
|
||||
BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Flush the TLB and return the address */
|
||||
HalpFlushTLB();
|
||||
return VirtualAddress;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
PHARDWARE_PTE PointerPte;
|
||||
ULONG i;
|
||||
|
||||
/* Only accept valid addresses */
|
||||
if (VirtualAddress < MM_HAL_VA_START) return;
|
||||
|
||||
/* Align it down to page size */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1));
|
||||
|
||||
/* Loop PTEs */
|
||||
PointerPte = HalAddressToPte(VirtualAddress);
|
||||
for (i = 0; i < PageCount; i++)
|
||||
{
|
||||
*(PULONG)PointerPte = 0;
|
||||
PointerPte++;
|
||||
}
|
||||
|
||||
/* Flush the TLB */
|
||||
HalpFlushTLB();
|
||||
|
||||
/* Put the heap back */
|
||||
if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
|
|
234
reactos/hal/halx86/generic/memory.c
Normal file
234
reactos/hal/halx86/generic/memory.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: hal/halx86/generic/memory.c
|
||||
* PURPOSE: HAL memory management
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Share with Mm headers? */
|
||||
#define MM_HAL_VA_START (PVOID)0xFFC00000
|
||||
#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024))
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
ULONG HalpUsedAllocDescriptors;
|
||||
MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64];
|
||||
PVOID HalpHeapStart = MM_HAL_HEAP_START;
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN ULONG MaxAddress,
|
||||
IN ULONG PageCount,
|
||||
IN BOOLEAN Aligned)
|
||||
{
|
||||
ULONG UsedDescriptors, Alignment, PhysicalAddress;
|
||||
PFN_NUMBER MaxPage, BasePage;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;
|
||||
|
||||
/* Highest page we'll go */
|
||||
MaxPage = MaxAddress >> PAGE_SHIFT;
|
||||
|
||||
/* We need at least two blocks */
|
||||
if ((HalpUsedAllocDescriptors + 2) > 64) return 0;
|
||||
|
||||
/* Remember how many we have now */
|
||||
UsedDescriptors = HalpUsedAllocDescriptors;
|
||||
|
||||
/* Loop the loader block memory descriptors */
|
||||
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||||
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
|
||||
{
|
||||
/* Get the block */
|
||||
MdBlock = CONTAINING_RECORD(NextEntry,
|
||||
MEMORY_ALLOCATION_DESCRIPTOR,
|
||||
ListEntry);
|
||||
|
||||
/* No alignment by default */
|
||||
Alignment = 0;
|
||||
|
||||
/* Unless requested, in which case we use a 64KB block alignment */
|
||||
if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;
|
||||
|
||||
/* Search for free memory */
|
||||
if ((MdBlock->MemoryType == LoaderFree) ||
|
||||
(MdBlock->MemoryType == LoaderFirmwareTemporary))
|
||||
{
|
||||
/* Make sure the page is within bounds, including alignment */
|
||||
BasePage = MdBlock->BasePage;
|
||||
if ((BasePage) &&
|
||||
(MdBlock->PageCount >= PageCount + Alignment) &&
|
||||
(BasePage + PageCount + Alignment < MaxPage))
|
||||
{
|
||||
|
||||
/* We found an address */
|
||||
PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep trying */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* If we didn't find anything, get out of here */
|
||||
if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;
|
||||
|
||||
/* Okay, now get a descriptor */
|
||||
NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors];
|
||||
NewBlock->PageCount = PageCount;
|
||||
NewBlock->BasePage = MdBlock->BasePage + Alignment;
|
||||
NewBlock->MemoryType = LoaderHALCachedMemory;
|
||||
|
||||
/* Update count */
|
||||
UsedDescriptors++;
|
||||
HalpUsedAllocDescriptors = UsedDescriptors;
|
||||
|
||||
/* Check if we had any alignment */
|
||||
if (Alignment)
|
||||
{
|
||||
/* Check if we had leftovers */
|
||||
if ((MdBlock->PageCount - Alignment) != PageCount)
|
||||
{
|
||||
/* Get the next descriptor */
|
||||
FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
|
||||
FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount;
|
||||
FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount;
|
||||
|
||||
/* One more */
|
||||
HalpUsedAllocDescriptors++;
|
||||
|
||||
/* Insert it into the list */
|
||||
InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
|
||||
}
|
||||
|
||||
/* Use this descriptor */
|
||||
NewBlock->PageCount = Alignment;
|
||||
InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Consume memory from this block */
|
||||
MdBlock->BasePage += PageCount;
|
||||
MdBlock->PageCount -= PageCount;
|
||||
|
||||
/* Insert the descriptor */
|
||||
InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);
|
||||
|
||||
/* Remove the entry if the whole block was allocated */
|
||||
if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
|
||||
}
|
||||
|
||||
/* Return the address */
|
||||
return PhysicalAddress;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
PHARDWARE_PTE PointerPte;
|
||||
ULONG UsedPages = 0;
|
||||
PVOID VirtualAddress, BaseAddress;
|
||||
|
||||
/* Start at the current HAL heap base */
|
||||
BaseAddress = HalpHeapStart;
|
||||
VirtualAddress = BaseAddress;
|
||||
|
||||
/* Loop until we have all the pages required */
|
||||
while (UsedPages < PageCount)
|
||||
{
|
||||
/* If this overflows past the HAL heap, it means there's no space */
|
||||
if (VirtualAddress == NULL) return NULL;
|
||||
|
||||
/* Get the PTE for this address */
|
||||
PointerPte = HalAddressToPte(VirtualAddress);
|
||||
|
||||
/* Go to the next page */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
|
||||
|
||||
/* Check if the page is available */
|
||||
if (PointerPte->Valid)
|
||||
{
|
||||
/* PTE has data, skip it and start with a new base address */
|
||||
BaseAddress = VirtualAddress;
|
||||
UsedPages = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* PTE is available, keep going on this run */
|
||||
UsedPages++;
|
||||
}
|
||||
|
||||
/* Take the base address of the page plus the actual offset in the address */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress +
|
||||
BYTE_OFFSET(PhysicalAddress.LowPart));
|
||||
|
||||
/* If we are starting at the heap, move the heap */
|
||||
if (BaseAddress == HalpHeapStart)
|
||||
{
|
||||
/* Past this allocation */
|
||||
HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE));
|
||||
}
|
||||
|
||||
/* Loop pages that can be mapped */
|
||||
while (UsedPages--)
|
||||
{
|
||||
/* Fill out the PTE */
|
||||
PointerPte = HalAddressToPte(BaseAddress);
|
||||
PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT;
|
||||
PointerPte->Valid = 1;
|
||||
PointerPte->Write = 1;
|
||||
|
||||
/* Move to the next address */
|
||||
PhysicalAddress.QuadPart += PAGE_SIZE;
|
||||
BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Flush the TLB and return the address */
|
||||
HalpFlushTLB();
|
||||
return VirtualAddress;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
|
||||
IN ULONG PageCount)
|
||||
{
|
||||
PHARDWARE_PTE PointerPte;
|
||||
ULONG i;
|
||||
|
||||
/* Only accept valid addresses */
|
||||
if (VirtualAddress < MM_HAL_VA_START) return;
|
||||
|
||||
/* Align it down to page size */
|
||||
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1));
|
||||
|
||||
/* Loop PTEs */
|
||||
PointerPte = HalAddressToPte(VirtualAddress);
|
||||
for (i = 0; i < PageCount; i++)
|
||||
{
|
||||
*(PULONG)PointerPte = 0;
|
||||
PointerPte++;
|
||||
}
|
||||
|
||||
/* Flush the TLB */
|
||||
HalpFlushTLB();
|
||||
|
||||
/* Put the heap back */
|
||||
if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<file>display.c</file>
|
||||
<file>dma.c</file>
|
||||
<file>drive.c</file>
|
||||
<file>halinit.c</file>
|
||||
<file>memory.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>profil.c</file>
|
||||
<file>reboot.c</file>
|
||||
|
@ -29,6 +29,7 @@
|
|||
<file>usage.c</file>
|
||||
<if property="ARCH" value="i386">
|
||||
<file>bios.c</file>
|
||||
<file>halinit.c</file>
|
||||
<directory name="i386">
|
||||
<file>portio.c</file>
|
||||
<file>systimer.S</file>
|
||||
|
@ -46,7 +47,7 @@
|
|||
<!-- file>apic.c</file -->
|
||||
<file>systimer.S</file>
|
||||
<!-- file>usage.c</file -->
|
||||
</directory>
|
||||
</directory>
|
||||
</if>
|
||||
</directory>
|
||||
<directory name="include">
|
||||
|
|
Loading…
Reference in a new issue