[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:
Timo Kreuzer 2011-09-22 07:52:51 +00:00
parent 2625559397
commit 53d96bda2f
6 changed files with 360 additions and 358 deletions

View file

@ -33,7 +33,6 @@ list(APPEND FREELDR_COMMON_SOURCE
options.c
oslist.c
version.c
arcemul/mm.c
arcemul/time.c
cache/blocklist.c
cache/cache.c
@ -53,6 +52,7 @@ list(APPEND FREELDR_COMMON_SOURCE
inifile/parse.c
mm/meminit.c
mm/mm.c
mm/heap.c
reactos/registry.c
reactos/arcname.c
reactos/archwsup.c

View file

@ -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;
}
}
}

View file

@ -9,7 +9,6 @@
<define name="_NTHAL_" />
<define name="_NTSYSTEM_" />
<directory name="arcemul">
<file>mm.c</file>
<file>time.c</file>
</directory>
<directory name="cache">
@ -41,6 +40,7 @@
<file>parse.c</file>
</directory>
<directory name="mm">
<file>heap.c</file>
<file>meminit.c</file>
<file>mm.c</file>
</directory>

View 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;
}

View file

@ -56,6 +56,215 @@ ULONG MmHighestPhysicalPage = 0;
extern ULONG_PTR MmHeapPointer;
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)
{
#if DBG
@ -102,40 +311,6 @@ BOOLEAN MmInitializeMemoryManager(VOID)
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
PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
{
@ -178,7 +353,7 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
//
if (MemoryDescriptor->MemoryType == MemoryFree) MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
}
//
// Check if we got a higher (usable) start page address
//
@ -190,7 +365,7 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage;
}
}
TRACE("lo/hi %lx %lxn", MmLowestPhysicalPage, MmHighestPhysicalPage);
PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);

View file

@ -82,42 +82,6 @@ PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
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)
{
// Temporary forwarder...
@ -345,64 +309,3 @@ PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries)
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;
}