diff --git a/reactos/hal/halx86/generic/halinit.c b/reactos/hal/halx86/generic/halinit.c index db54eb59d63..6a6b1660694 100644 --- a/reactos/hal/halx86/generic/halinit.c +++ b/reactos/hal/halx86/generic/halinit.c @@ -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) diff --git a/reactos/hal/halx86/generic/memory.c b/reactos/hal/halx86/generic/memory.c new file mode 100644 index 00000000000..74f20cbc6ed --- /dev/null +++ b/reactos/hal/halx86/generic/memory.c @@ -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 +#define NDEBUG +#include + +/* 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; +} + diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index 3532d001d18..ed5ec3a00cf 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -20,7 +20,7 @@ display.c dma.c drive.c - halinit.c + memory.c misc.c profil.c reboot.c @@ -29,6 +29,7 @@ usage.c bios.c + halinit.c portio.c systimer.S @@ -46,7 +47,7 @@ systimer.S - +