mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[FREELDR]
- Move heap code out of mm.c into a seperate file mm/heap.c - Move code from arcemul/mm.c into mm/mminit.c svn path=/trunk/; revision=53801
This commit is contained in:
parent
2625559397
commit
53d96bda2f
6 changed files with 360 additions and 358 deletions
|
@ -33,7 +33,6 @@ list(APPEND FREELDR_COMMON_SOURCE
|
||||||
options.c
|
options.c
|
||||||
oslist.c
|
oslist.c
|
||||||
version.c
|
version.c
|
||||||
arcemul/mm.c
|
|
||||||
arcemul/time.c
|
arcemul/time.c
|
||||||
cache/blocklist.c
|
cache/blocklist.c
|
||||||
cache/cache.c
|
cache/cache.c
|
||||||
|
@ -53,6 +52,7 @@ list(APPEND FREELDR_COMMON_SOURCE
|
||||||
inifile/parse.c
|
inifile/parse.c
|
||||||
mm/meminit.c
|
mm/meminit.c
|
||||||
mm/mm.c
|
mm/mm.c
|
||||||
|
mm/heap.c
|
||||||
reactos/registry.c
|
reactos/registry.c
|
||||||
reactos/arcname.c
|
reactos/arcname.c
|
||||||
reactos/archwsup.c
|
reactos/archwsup.c
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS Boot Loader (FreeLDR)
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
|
||||||
* FILE: boot/freeldr/freeldr/arcemul/mm.c
|
|
||||||
* PURPOSE: Routines for ARC Memory Management
|
|
||||||
* PROGRAMMERS: Hervé Poussineau <hpoussin@reactos.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
|
||||||
|
|
||||||
#include <freeldr.h>
|
|
||||||
#define NDEBUG
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MEMORY_DESCRIPTOR m;
|
|
||||||
ULONG Index;
|
|
||||||
BOOLEAN GeneratedDescriptor;
|
|
||||||
} MEMORY_DESCRIPTOR_INT;
|
|
||||||
static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
|
|
||||||
{
|
|
||||||
#if defined (__i386__) || defined (_M_AMD64)
|
|
||||||
{ { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
|
|
||||||
{ { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
|
|
||||||
{ { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
|
|
||||||
{ { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
|
|
||||||
{ { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
|
|
||||||
{ { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
|
|
||||||
{ { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
|
|
||||||
{ { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
|
|
||||||
#elif __arm__ // This needs to be done per-platform specific way
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static
|
|
||||||
VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
|
|
||||||
{
|
|
||||||
int Index;
|
|
||||||
int Index2;
|
|
||||||
ULONGLONG BaseAddressOffset;
|
|
||||||
|
|
||||||
// Loop through each entry in the array
|
|
||||||
for (Index=0; Index<*MapCount; Index++)
|
|
||||||
{
|
|
||||||
// Correct all the addresses to be aligned on page boundaries
|
|
||||||
BaseAddressOffset = ROUND_UP(BiosMemoryMap[Index].BaseAddress, MM_PAGE_SIZE) - BiosMemoryMap[Index].BaseAddress;
|
|
||||||
BiosMemoryMap[Index].BaseAddress += BaseAddressOffset;
|
|
||||||
if (BiosMemoryMap[Index].Length < BaseAddressOffset)
|
|
||||||
{
|
|
||||||
BiosMemoryMap[Index].Length = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BiosMemoryMap[Index].Length -= BaseAddressOffset;
|
|
||||||
}
|
|
||||||
BiosMemoryMap[Index].Length = ROUND_DOWN(BiosMemoryMap[Index].Length, MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
// If the entry type isn't usable then remove
|
|
||||||
// it from the memory map (this will help reduce
|
|
||||||
// the size of our lookup table)
|
|
||||||
// If the length is less than a full page then
|
|
||||||
// get rid of it also.
|
|
||||||
if (BiosMemoryMap[Index].Type != BiosMemoryUsable ||
|
|
||||||
BiosMemoryMap[Index].Length < MM_PAGE_SIZE)
|
|
||||||
{
|
|
||||||
// Slide every entry after this down one
|
|
||||||
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
|
|
||||||
{
|
|
||||||
BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
|
|
||||||
}
|
|
||||||
(*MapCount)--;
|
|
||||||
Index--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const MEMORY_DESCRIPTOR*
|
|
||||||
ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
|
|
||||||
{
|
|
||||||
MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
|
|
||||||
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
|
||||||
static ULONG BiosMemoryMapEntryCount;
|
|
||||||
static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
|
|
||||||
static BOOLEAN MemoryMapInitialized = FALSE;
|
|
||||||
ULONG i, j;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if it is the first time we're called
|
|
||||||
//
|
|
||||||
if (!MemoryMapInitialized)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Get the machine generated memory map
|
|
||||||
//
|
|
||||||
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
|
||||||
BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
|
|
||||||
sizeof(BiosMemoryMap) /
|
|
||||||
sizeof(BIOS_MEMORY_MAP));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fix entries that are not page aligned
|
|
||||||
//
|
|
||||||
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Copy the entries to our structure
|
|
||||||
//
|
|
||||||
for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Is it suitable memory?
|
|
||||||
//
|
|
||||||
if (BiosMemoryMap[i].Type != BiosMemoryUsable)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// No. Process next descriptor
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Copy this memory descriptor
|
|
||||||
//
|
|
||||||
BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
|
|
||||||
BiosMemoryDescriptors[j].m.BasePage = (ULONG)(BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE);
|
|
||||||
BiosMemoryDescriptors[j].m.PageCount = (ULONG)(BiosMemoryMap[i].Length / MM_PAGE_SIZE);
|
|
||||||
BiosMemoryDescriptors[j].Index = j;
|
|
||||||
BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Remember how much descriptors we found
|
|
||||||
//
|
|
||||||
BiosMemoryMapEntryCount = j;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Mark memory map as already retrieved and initialized
|
|
||||||
//
|
|
||||||
MemoryMapInitialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
|
|
||||||
|
|
||||||
if (Current == NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// First descriptor requested
|
|
||||||
//
|
|
||||||
if (BiosMemoryMapEntryCount > 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Return first generated memory descriptor
|
|
||||||
//
|
|
||||||
return &BiosMemoryDescriptors[0].m;
|
|
||||||
}
|
|
||||||
else if (sizeof(MemoryDescriptors) > 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Return first fixed memory descriptor
|
|
||||||
//
|
|
||||||
return &MemoryDescriptors[0].m;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Strange case, we have no memory descriptor
|
|
||||||
//
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (CurrentDescriptor->GeneratedDescriptor)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Current entry is a generated descriptor
|
|
||||||
//
|
|
||||||
if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Return next generated descriptor
|
|
||||||
//
|
|
||||||
return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
|
||||||
}
|
|
||||||
else if (sizeof(MemoryDescriptors) > 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Return first fixed memory descriptor
|
|
||||||
//
|
|
||||||
return &MemoryDescriptors[0].m;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// No fixed memory descriptor; end of memory map
|
|
||||||
//
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Current entry is a fixed descriptor
|
|
||||||
//
|
|
||||||
if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Return next fixed descriptor
|
|
||||||
//
|
|
||||||
return &MemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// No more fixed memory descriptor; end of memory map
|
|
||||||
//
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@
|
||||||
<define name="_NTHAL_" />
|
<define name="_NTHAL_" />
|
||||||
<define name="_NTSYSTEM_" />
|
<define name="_NTSYSTEM_" />
|
||||||
<directory name="arcemul">
|
<directory name="arcemul">
|
||||||
<file>mm.c</file>
|
|
||||||
<file>time.c</file>
|
<file>time.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="cache">
|
<directory name="cache">
|
||||||
|
@ -41,6 +40,7 @@
|
||||||
<file>parse.c</file>
|
<file>parse.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="mm">
|
<directory name="mm">
|
||||||
|
<file>heap.c</file>
|
||||||
<file>meminit.c</file>
|
<file>meminit.c</file>
|
||||||
<file>mm.c</file>
|
<file>mm.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
|
|
147
reactos/boot/freeldr/freeldr/mm/heap.c
Normal file
147
reactos/boot/freeldr/freeldr/mm/heap.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* FreeLoader
|
||||||
|
* Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <freeldr.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
DBG_DEFAULT_CHANNEL(MEMORY);
|
||||||
|
|
||||||
|
VOID MmInitializeHeap(PVOID PageLookupTable)
|
||||||
|
{
|
||||||
|
ULONG PagesNeeded = 0;
|
||||||
|
ULONG HeapStart = 0;
|
||||||
|
|
||||||
|
// Find contigious memory block for HEAP:STACK
|
||||||
|
PagesNeeded = HEAP_PAGES + STACK_PAGES;
|
||||||
|
HeapStart = MmFindAvailablePages(PageLookupTable, TotalPagesInLookupTable, PagesNeeded, FALSE);
|
||||||
|
|
||||||
|
if (HeapStart == 0)
|
||||||
|
{
|
||||||
|
UiMessageBox("Critical error: Can't allocate heap!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize BGET
|
||||||
|
bpool(HeapStart << MM_PAGE_SHIFT, PagesNeeded << MM_PAGE_SHIFT);
|
||||||
|
|
||||||
|
// Mark those pages as used
|
||||||
|
MmMarkPagesInLookupTable(PageLookupTableAddress, HeapStart, PagesNeeded, LoaderOsloaderHeap);
|
||||||
|
|
||||||
|
TRACE("Heap initialized, base 0x%08x, pages %d\n", (HeapStart << MM_PAGE_SHIFT), PagesNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID MmHeapAlloc(ULONG MemorySize)
|
||||||
|
{
|
||||||
|
PVOID Result;
|
||||||
|
|
||||||
|
if (MemorySize > MM_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
WARN("Consider using other functions to allocate %d bytes of memory!\n", MemorySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the buffer from BGET pool
|
||||||
|
Result = bget(MemorySize);
|
||||||
|
|
||||||
|
if (Result == NULL)
|
||||||
|
{
|
||||||
|
ERR("Heap allocation for %d bytes failed\n", MemorySize);
|
||||||
|
}
|
||||||
|
#if MM_DBG
|
||||||
|
{
|
||||||
|
LONG CurAlloc, TotalFree, MaxFree, NumberOfGets, NumberOfRels;
|
||||||
|
|
||||||
|
// Gather some stats
|
||||||
|
bstats(&CurAlloc, &TotalFree, &MaxFree, &NumberOfGets, &NumberOfRels);
|
||||||
|
|
||||||
|
TRACE("Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
|
||||||
|
CurAlloc, TotalFree, NumberOfGets, NumberOfRels);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID MmHeapFree(PVOID MemoryPointer)
|
||||||
|
{
|
||||||
|
// Release the buffer to the pool
|
||||||
|
brel(MemoryPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#undef ExAllocatePoolWithTag
|
||||||
|
NTKERNELAPI
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
ExAllocatePoolWithTag(
|
||||||
|
IN POOL_TYPE PoolType,
|
||||||
|
IN SIZE_T NumberOfBytes,
|
||||||
|
IN ULONG Tag)
|
||||||
|
{
|
||||||
|
return MmHeapAlloc(NumberOfBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ExFreePool
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ExFreePool(
|
||||||
|
IN PVOID P)
|
||||||
|
{
|
||||||
|
MmHeapFree(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ExFreePoolWithTag
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ExFreePoolWithTag(
|
||||||
|
IN PVOID P,
|
||||||
|
IN ULONG Tag)
|
||||||
|
{
|
||||||
|
ExFreePool(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
RtlAllocateHeap(
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN ULONG Flags,
|
||||||
|
IN SIZE_T Size)
|
||||||
|
{
|
||||||
|
PVOID ptr;
|
||||||
|
|
||||||
|
ptr = MmHeapAlloc(Size);
|
||||||
|
if (ptr && (Flags & HEAP_ZERO_MEMORY))
|
||||||
|
{
|
||||||
|
RtlZeroMemory(ptr, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
RtlFreeHeap(
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN ULONG Flags,
|
||||||
|
IN PVOID HeapBase)
|
||||||
|
{
|
||||||
|
MmHeapFree(HeapBase);
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -56,6 +56,215 @@ ULONG MmHighestPhysicalPage = 0;
|
||||||
extern ULONG_PTR MmHeapPointer;
|
extern ULONG_PTR MmHeapPointer;
|
||||||
extern ULONG_PTR MmHeapStart;
|
extern ULONG_PTR MmHeapStart;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MEMORY_DESCRIPTOR m;
|
||||||
|
ULONG Index;
|
||||||
|
BOOLEAN GeneratedDescriptor;
|
||||||
|
} MEMORY_DESCRIPTOR_INT;
|
||||||
|
static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
|
||||||
|
{
|
||||||
|
#if defined (__i386__) || defined (_M_AMD64)
|
||||||
|
{ { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
|
||||||
|
{ { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
|
||||||
|
{ { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
|
||||||
|
{ { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
|
||||||
|
{ { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
|
||||||
|
{ { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
|
||||||
|
{ { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
|
||||||
|
{ { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
|
||||||
|
#elif __arm__ // This needs to be done per-platform specific way
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
int Index2;
|
||||||
|
ULONGLONG BaseAddressOffset;
|
||||||
|
|
||||||
|
// Loop through each entry in the array
|
||||||
|
for (Index=0; Index<*MapCount; Index++)
|
||||||
|
{
|
||||||
|
// Correct all the addresses to be aligned on page boundaries
|
||||||
|
BaseAddressOffset = ROUND_UP(BiosMemoryMap[Index].BaseAddress, MM_PAGE_SIZE) - BiosMemoryMap[Index].BaseAddress;
|
||||||
|
BiosMemoryMap[Index].BaseAddress += BaseAddressOffset;
|
||||||
|
if (BiosMemoryMap[Index].Length < BaseAddressOffset)
|
||||||
|
{
|
||||||
|
BiosMemoryMap[Index].Length = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BiosMemoryMap[Index].Length -= BaseAddressOffset;
|
||||||
|
}
|
||||||
|
BiosMemoryMap[Index].Length = ROUND_DOWN(BiosMemoryMap[Index].Length, MM_PAGE_SIZE);
|
||||||
|
|
||||||
|
// If the entry type isn't usable then remove
|
||||||
|
// it from the memory map (this will help reduce
|
||||||
|
// the size of our lookup table)
|
||||||
|
// If the length is less than a full page then
|
||||||
|
// get rid of it also.
|
||||||
|
if (BiosMemoryMap[Index].Type != BiosMemoryUsable ||
|
||||||
|
BiosMemoryMap[Index].Length < MM_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
// Slide every entry after this down one
|
||||||
|
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
|
||||||
|
{
|
||||||
|
BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
|
||||||
|
}
|
||||||
|
(*MapCount)--;
|
||||||
|
Index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const MEMORY_DESCRIPTOR*
|
||||||
|
ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
|
||||||
|
{
|
||||||
|
MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
|
||||||
|
BIOS_MEMORY_MAP BiosMemoryMap[32];
|
||||||
|
static ULONG BiosMemoryMapEntryCount;
|
||||||
|
static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
|
||||||
|
static BOOLEAN MemoryMapInitialized = FALSE;
|
||||||
|
ULONG i, j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it is the first time we're called
|
||||||
|
//
|
||||||
|
if (!MemoryMapInitialized)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Get the machine generated memory map
|
||||||
|
//
|
||||||
|
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
||||||
|
BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
|
||||||
|
sizeof(BiosMemoryMap) /
|
||||||
|
sizeof(BIOS_MEMORY_MAP));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix entries that are not page aligned
|
||||||
|
//
|
||||||
|
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the entries to our structure
|
||||||
|
//
|
||||||
|
for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Is it suitable memory?
|
||||||
|
//
|
||||||
|
if (BiosMemoryMap[i].Type != BiosMemoryUsable)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No. Process next descriptor
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy this memory descriptor
|
||||||
|
//
|
||||||
|
BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
|
||||||
|
BiosMemoryDescriptors[j].m.BasePage = (ULONG)(BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE);
|
||||||
|
BiosMemoryDescriptors[j].m.PageCount = (ULONG)(BiosMemoryMap[i].Length / MM_PAGE_SIZE);
|
||||||
|
BiosMemoryDescriptors[j].Index = j;
|
||||||
|
BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remember how much descriptors we found
|
||||||
|
//
|
||||||
|
BiosMemoryMapEntryCount = j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mark memory map as already retrieved and initialized
|
||||||
|
//
|
||||||
|
MemoryMapInitialized = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
|
||||||
|
|
||||||
|
if (Current == NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// First descriptor requested
|
||||||
|
//
|
||||||
|
if (BiosMemoryMapEntryCount > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first generated memory descriptor
|
||||||
|
//
|
||||||
|
return &BiosMemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else if (sizeof(MemoryDescriptors) > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first fixed memory descriptor
|
||||||
|
//
|
||||||
|
return &MemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Strange case, we have no memory descriptor
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CurrentDescriptor->GeneratedDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Current entry is a generated descriptor
|
||||||
|
//
|
||||||
|
if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return next generated descriptor
|
||||||
|
//
|
||||||
|
return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
||||||
|
}
|
||||||
|
else if (sizeof(MemoryDescriptors) > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return first fixed memory descriptor
|
||||||
|
//
|
||||||
|
return &MemoryDescriptors[0].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No fixed memory descriptor; end of memory map
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Current entry is a fixed descriptor
|
||||||
|
//
|
||||||
|
if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return next fixed descriptor
|
||||||
|
//
|
||||||
|
return &MemoryDescriptors[CurrentDescriptor->Index + 1].m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No more fixed memory descriptor; end of memory map
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN MmInitializeMemoryManager(VOID)
|
BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
{
|
{
|
||||||
#if DBG
|
#if DBG
|
||||||
|
@ -102,40 +311,6 @@ BOOLEAN MmInitializeMemoryManager(VOID)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID MmInitializeHeap(PVOID PageLookupTable)
|
|
||||||
{
|
|
||||||
ULONG PagesNeeded;
|
|
||||||
ULONG HeapStart;
|
|
||||||
#ifndef _M_ARM
|
|
||||||
MEMORY_TYPE Type;
|
|
||||||
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
|
|
||||||
|
|
||||||
// HACK: Make it so it doesn't overlap kernel space
|
|
||||||
Type = RealPageLookupTable[0x100].PageAllocated;
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, LoaderSystemCode);
|
|
||||||
#endif
|
|
||||||
// Find contigious memory block for HEAP:STACK
|
|
||||||
PagesNeeded = HEAP_PAGES + STACK_PAGES;
|
|
||||||
HeapStart = MmFindAvailablePages(PageLookupTable, TotalPagesInLookupTable, PagesNeeded, FALSE);
|
|
||||||
#ifndef _M_ARM
|
|
||||||
// Unapply the hack
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, 0x100, 0xFF, Type);
|
|
||||||
#endif
|
|
||||||
if (HeapStart == 0)
|
|
||||||
{
|
|
||||||
UiMessageBox("Critical error: Can't allocate heap!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize BGET
|
|
||||||
bpool(HeapStart << MM_PAGE_SHIFT, PagesNeeded << MM_PAGE_SHIFT);
|
|
||||||
|
|
||||||
// Mark those pages as used
|
|
||||||
MmMarkPagesInLookupTable(PageLookupTableAddress, HeapStart, PagesNeeded, LoaderOsloaderHeap);
|
|
||||||
|
|
||||||
TRACE("Heap initialized, base 0x%08x, pages %d\n", (HeapStart << MM_PAGE_SHIFT), PagesNeeded);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
|
PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +353,7 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
|
||||||
//
|
//
|
||||||
if (MemoryDescriptor->MemoryType == MemoryFree) MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
|
if (MemoryDescriptor->MemoryType == MemoryFree) MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if we got a higher (usable) start page address
|
// Check if we got a higher (usable) start page address
|
||||||
//
|
//
|
||||||
|
@ -190,7 +365,7 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
|
||||||
if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage;
|
if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("lo/hi %lx %lxn", MmLowestPhysicalPage, MmHighestPhysicalPage);
|
TRACE("lo/hi %lx %lxn", MmLowestPhysicalPage, MmHighestPhysicalPage);
|
||||||
PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
|
PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
|
||||||
TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
|
TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
|
||||||
|
|
|
@ -82,42 +82,6 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
|
||||||
return MemPointer;
|
return MemPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID MmHeapAlloc(ULONG MemorySize)
|
|
||||||
{
|
|
||||||
PVOID Result;
|
|
||||||
|
|
||||||
if (MemorySize > MM_PAGE_SIZE)
|
|
||||||
{
|
|
||||||
WARN("Consider using other functions to allocate %d bytes of memory!\n", MemorySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the buffer from BGET pool
|
|
||||||
Result = bget(MemorySize);
|
|
||||||
|
|
||||||
if (Result == NULL)
|
|
||||||
{
|
|
||||||
ERR("Heap allocation for %d bytes failed\n", MemorySize);
|
|
||||||
}
|
|
||||||
#if MM_DBG
|
|
||||||
{
|
|
||||||
LONG CurAlloc, TotalFree, MaxFree, NumberOfGets, NumberOfRels;
|
|
||||||
|
|
||||||
// Gather some stats
|
|
||||||
bstats(&CurAlloc, &TotalFree, &MaxFree, &NumberOfGets, &NumberOfRels);
|
|
||||||
|
|
||||||
TRACE("Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
|
|
||||||
CurAlloc, TotalFree, NumberOfGets, NumberOfRels);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID MmHeapFree(PVOID MemoryPointer)
|
|
||||||
{
|
|
||||||
// Release the buffer to the pool
|
|
||||||
brel(MemoryPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID MmAllocateMemory(ULONG MemorySize)
|
PVOID MmAllocateMemory(ULONG MemorySize)
|
||||||
{
|
{
|
||||||
// Temporary forwarder...
|
// Temporary forwarder...
|
||||||
|
@ -345,64 +309,3 @@ PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries)
|
||||||
return RealPageLookupTable;
|
return RealPageLookupTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ExAllocatePoolWithTag
|
|
||||||
NTKERNELAPI
|
|
||||||
PVOID
|
|
||||||
NTAPI
|
|
||||||
ExAllocatePoolWithTag(
|
|
||||||
IN POOL_TYPE PoolType,
|
|
||||||
IN SIZE_T NumberOfBytes,
|
|
||||||
IN ULONG Tag)
|
|
||||||
{
|
|
||||||
return MmHeapAlloc(NumberOfBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef ExFreePool
|
|
||||||
NTKERNELAPI
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ExFreePool(
|
|
||||||
IN PVOID P)
|
|
||||||
{
|
|
||||||
MmHeapFree(P);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef ExFreePoolWithTag
|
|
||||||
NTKERNELAPI
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ExFreePoolWithTag(
|
|
||||||
IN PVOID P,
|
|
||||||
IN ULONG Tag)
|
|
||||||
{
|
|
||||||
ExFreePool(P);
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
NTAPI
|
|
||||||
RtlAllocateHeap(
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN ULONG Flags,
|
|
||||||
IN SIZE_T Size)
|
|
||||||
{
|
|
||||||
PVOID ptr;
|
|
||||||
|
|
||||||
ptr = MmHeapAlloc(Size);
|
|
||||||
if (ptr && (Flags & HEAP_ZERO_MEMORY))
|
|
||||||
{
|
|
||||||
RtlZeroMemory(ptr, Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
NTAPI
|
|
||||||
RtlFreeHeap(
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN ULONG Flags,
|
|
||||||
IN PVOID HeapBase)
|
|
||||||
{
|
|
||||||
MmHeapFree(HeapBase);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue