mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.4 KiB
179 lines
4.4 KiB
//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk35/src/hal/halsni/mips/RCS/xxmemory.c,v 1.2 1994/11/09 07:54:26 holli Exp $")
|
|
|
|
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
xxmemory.c
|
|
|
|
Abstract:
|
|
|
|
Provides routines to allow the HAL to map physical memory.
|
|
|
|
Environment:
|
|
|
|
Phase 0 initialization only.
|
|
|
|
Changes:
|
|
|
|
All stuff comes from the x86 HAL Sources (xxmemory.c)
|
|
|
|
--*/
|
|
#include "halp.h"
|
|
|
|
//
|
|
// Put all code for HAL initialization in the INIT section. It will be
|
|
// deallocated by memory management when phase 1 initialization is
|
|
// completed.
|
|
//
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
#pragma alloc_text(INIT, HalpAllocPhysicalMemory)
|
|
#endif
|
|
|
|
|
|
MEMORY_ALLOCATION_DESCRIPTOR HalpExtraAllocationDescriptor;
|
|
|
|
ULONG
|
|
HalpAllocPhysicalMemory(
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|
IN ULONG MaxPhysicalAddress,
|
|
IN ULONG NoPages,
|
|
IN BOOLEAN bAlignOn64k
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Carves out N pages of physical memory from the memory descriptor
|
|
list in the desired location. This function is to be called only
|
|
during phase zero initialization. (ie, before the kernel's memory
|
|
management system is running)
|
|
|
|
Arguments:
|
|
|
|
MaxPhysicalAddress - The max address where the physical memory can be
|
|
NoPages - Number of pages to allocate
|
|
|
|
Return Value:
|
|
|
|
The pyhsical address or NULL if the memory could not be obtained.
|
|
|
|
--*/
|
|
{
|
|
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
|
|
PLIST_ENTRY NextMd;
|
|
ULONG AlignmentOffset;
|
|
ULONG MaxPageAddress;
|
|
ULONG PhysicalAddress;
|
|
|
|
|
|
MaxPageAddress = MaxPhysicalAddress >> PAGE_SHIFT;
|
|
|
|
|
|
//
|
|
// Scan the memory allocation descriptors and allocate map buffers
|
|
//
|
|
|
|
NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
|
|
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
|
|
Descriptor = CONTAINING_RECORD(NextMd,
|
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
|
ListEntry);
|
|
|
|
AlignmentOffset = bAlignOn64k ?
|
|
((Descriptor->BasePage + 0x0f) & ~0x0f) - Descriptor->BasePage :
|
|
0;
|
|
|
|
//
|
|
// Search for a block of memory which contains a memory chunk
|
|
// that is greater than size pages, and has a physical address less
|
|
// than MAXIMUM_PHYSICAL_ADDRESS.
|
|
//
|
|
|
|
if ((Descriptor->MemoryType == LoaderFree ||
|
|
Descriptor->MemoryType == MemoryFirmwareTemporary) &&
|
|
(Descriptor->BasePage) &&
|
|
(Descriptor->PageCount >= NoPages + AlignmentOffset) &&
|
|
(Descriptor->BasePage + NoPages + AlignmentOffset < MaxPageAddress)) {
|
|
|
|
PhysicalAddress = (AlignmentOffset + Descriptor->BasePage)
|
|
<< PAGE_SHIFT;
|
|
|
|
break;
|
|
}
|
|
|
|
NextMd = NextMd->Flink;
|
|
}
|
|
|
|
//
|
|
// Use the extra descriptor to define the memory at the end of the
|
|
// original block.
|
|
//
|
|
|
|
|
|
ASSERT(NextMd != &LoaderBlock->MemoryDescriptorListHead);
|
|
|
|
if (NextMd == &LoaderBlock->MemoryDescriptorListHead)
|
|
|
|
return (ULONG)NULL;
|
|
|
|
//
|
|
// Adjust the memory descriptors.
|
|
//
|
|
|
|
if (AlignmentOffset == 0) {
|
|
|
|
Descriptor->BasePage += NoPages;
|
|
Descriptor->PageCount -= NoPages;
|
|
|
|
if (Descriptor->PageCount == 0) {
|
|
|
|
//
|
|
// The whole block was allocated,
|
|
// Remove the entry from the list completely.
|
|
//
|
|
|
|
RemoveEntryList(&Descriptor->ListEntry);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (Descriptor->PageCount - NoPages - AlignmentOffset) {
|
|
|
|
//
|
|
// Currently we only allow one Align64K allocation
|
|
//
|
|
ASSERT (HalpExtraAllocationDescriptor.PageCount == 0);
|
|
|
|
//
|
|
// The extra descriptor is needed so intialize it and insert
|
|
// it in the list.
|
|
//
|
|
HalpExtraAllocationDescriptor.PageCount =
|
|
Descriptor->PageCount - NoPages - AlignmentOffset;
|
|
|
|
HalpExtraAllocationDescriptor.BasePage =
|
|
Descriptor->BasePage + NoPages + AlignmentOffset;
|
|
|
|
HalpExtraAllocationDescriptor.MemoryType = MemoryFree;
|
|
InsertTailList(
|
|
&Descriptor->ListEntry,
|
|
&HalpExtraAllocationDescriptor.ListEntry
|
|
);
|
|
}
|
|
|
|
|
|
//
|
|
// Use the current entry as the descriptor for the first block.
|
|
//
|
|
|
|
Descriptor->PageCount = AlignmentOffset;
|
|
}
|
|
|
|
|
|
return PhysicalAddress;
|
|
}
|