Author: ion
Date: Sun Sep 6 16:41:43 2015
New Revision: 69059
URL:
http://svn.reactos.org/svn/reactos?rev=69059&view=rev
Log:
[BOOTMGFW]:
- Implement case in BlMmRemoveRegionFromMdlEx where the descriptor's tail (or entire
allocation) is contained in the descriptor -- this covers our BootMgr entry.
- Implement some more initialization functions.
- Start implementing the heap allocator initialization code. Now we need to implement the
actual page allocator.
Modified:
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
trunk/reactos/boot/environ/lib/mm/descriptor.c
trunk/reactos/boot/environ/lib/mm/heapalloc.c
trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
trunk/reactos/boot/environ/lib/mm/mm.c
trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -64,6 +64,8 @@
#define BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG 0x2000000
#define BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG 0x4000000
+#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000
+
#define BL_LIBRARY_FLAG_REINITIALIZE 0x02
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL 0x04
#define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED 0x20
@@ -71,6 +73,12 @@
#define BL_MEMORY_CLASS_SHIFT 28
/* ENUMERATIONS **************************************************************/
+
+typedef enum _BL_MEMORY_DESCRIPTOR_TYPE
+{
+ BlMdPhysical,
+ BlMdVirtual,
+} BL_MEMORY_DESCRIPTOR_TYPE;
typedef enum _BL_TRANSLATION_TYPE
{
@@ -144,6 +152,7 @@
// Loader Memory
//
BlLoaderMemory = 0xD0000002,
+ BlLoaderHeap = 0xD0000005,
BlLoaderPageDirectory = 0xD0000006,
BlLoaderReferencePage = 0xD0000007,
BlLoaderRamDisk = 0xD0000008,
@@ -397,6 +406,12 @@
ULONG Type;
} BL_MEMORY_DESCRIPTOR_LIST, *PBL_MEMORY_DESCRIPTOR_LIST;
+typedef struct _BL_ADDRESS_RANGE
+{
+ ULONGLONG Minimum;
+ ULONGLONG Maximum;
+} BL_ADDRESS_RANGE, *PBL_ADDRESS_RANGE;
+
/* INLINE ROUTINES ***********************************************************/
FORCEINLINE
@@ -554,6 +569,17 @@
__in PBL_MEMORY_DESCRIPTOR_LIST NewMdList
);
+NTSTATUS
+MmPapAllocatePagesInRange (
+ _Inout_ PULONG PhysicalAddress,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ ULONGLONG Pages,
+ _In_ ULONG Attributes,
+ _In_ ULONG Alignment,
+ _In_opt_ PBL_ADDRESS_RANGE Range,
+ _In_ ULONG Type
+ );
+
extern ULONG MmDescriptorCallTreeCount;
extern ULONG BlpApplicationFlags;
extern BL_LIBRARY_PARAMETERS BlpLibraryParameters;
Modified: trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/…
==============================================================================
--- trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] Sun Sep 6
16:41:43 2015
@@ -530,9 +530,11 @@
}
/* Loop the EFI memory map */
+#if 0
EarlyPrint(L"UEFI MEMORY MAP\n\n");
EarlyPrint(L"TYPE START END
ATTRIBUTES\n");
EarlyPrint(L"===============================================================\n");
+#endif
while (EfiMemoryMapSize != 0)
{
/* Check if this is an EFI buffer, but we're not in real mode */
@@ -571,13 +573,13 @@
{
goto LoopAgain;
}
-
+#if 0
EarlyPrint(L"%08X 0x%016I64X-0x%016I64X 0x%I64X\n",
MemoryType,
StartPage << PAGE_SHIFT,
EndPage << PAGE_SHIFT,
EfiDescriptor.Attribute);
-
+#endif
/* Check for any range of memory below 1MB */
if (StartPage < 0x100)
{
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descri…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -476,14 +476,6 @@
}
}
-typedef enum _BL_MEMORY_DESCRIPTOR_TYPE
-{
- BlMdPhysical,
- BlMdVirtual,
-} BL_MEMORY_DESCRIPTOR_TYPE;
-
-#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000
-
NTSTATUS
MmMdRemoveRegionFromMdlEx (
__in PBL_MEMORY_DESCRIPTOR_LIST MdList,
@@ -498,7 +490,11 @@
PLIST_ENTRY ListHead, NextEntry;
PBL_MEMORY_DESCRIPTOR Descriptor;
BL_MEMORY_DESCRIPTOR NewDescriptor;
+ ULONGLONG RegionSize;
ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
+
+ /* Set initial status */
+ Status = STATUS_SUCCESS;
/* Check if removed descriptors should go into a new list */
if (NewMdList != NULL)
@@ -551,7 +547,7 @@
FoundPageCount = Descriptor->PageCount;
FoundEndPage = FoundBasePage + FoundPageCount;
EndPage = PageCount + BasePage;
- EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in
0x%08I64X-0x%08I64X\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
+ //EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in
0x%08I64X-0x%08I64X\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
/* Make a copy of the original descriptor */
RtlCopyMemory(&NewDescriptor, NextEntry, sizeof(NewDescriptor));
@@ -566,28 +562,71 @@
if ((FoundBasePage >= BasePage) || (EndPage >= FoundEndPage))
{
/* This descriptor doesn't cover any part of the range */
- EarlyPrint(L"No part of this descriptor contains the
region\n");
+ //EarlyPrint(L"No part of this descriptor contains the
region\n");
}
else
{
/* This descriptor covers the head of the allocation */
- EarlyPrint(L"Descriptor covers the head of the region\n");
+ //EarlyPrint(L"Descriptor covers the head of the
region\n");
}
}
else
{
/* This descriptor contains the entire allocation */
- EarlyPrint(L"Descriptor contains the entire region\n");
- }
+ //EarlyPrint(L"Descriptor contains the entire region\n");
+ }
+
+ /* Keep going */
+ NextEntry = NextEntry->Flink;
}
else
{
- /* This descriptor covers the end of the allocation */
- EarlyPrint(L"Descriptor covers the end of the region\n");
- }
-
- /* Keep going */
- NextEntry = NextEntry->Flink;
+ /*
+ * This descriptor contains the end of the allocation. It may:
+ *
+ * - Contain the full allocation (i.e.: the start is aligned)
+ * - Contain parts of the end of the allocation (i.e.: the end is beyond)
+ * - Contain the entire tail end of the allocation (i..e:the end is within)
+ *
+ * So first, figure out if we cover the entire end or not
+ */
+ if (EndPage > FoundEndPage)
+ {
+ /* The allocation goes past the end of this descriptor */
+ EndPage = FoundEndPage;
+ }
+
+ /* This is how many pages we will eat away from the descriptor */
+ RegionSize = EndPage - FoundBasePage;
+
+ /* Update the descriptor to account for the consumed pages */
+ Descriptor->BasePage += RegionSize;
+ Descriptor->PageCount -= RegionSize;
+ if (Descriptor->VirtualPage)
+ {
+ Descriptor->VirtualPage += RegionSize;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+
+ /* Check if the descriptor is now empty */
+ if (!Descriptor->PageCount)
+ {
+ /* Remove it */
+ //EarlyPrint(L"Entire descriptor consumed\n");
+ MmMdRemoveDescriptorFromList(MdList, Descriptor);
+ MmMdFreeDescriptor(Descriptor);
+
+ /* Check if we're supposed to insert it into a new list */
+ if (HaveNewList)
+ {
+ EarlyPrint(L"Not yet implemented\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Quickie;
+ }
+ }
+ }
}
Quickie:
Modified: trunk/reactos/boot/environ/lib/mm/heapalloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/heapal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/heapalloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/heapalloc.c [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -12,8 +12,149 @@
/* DATA VARIABLES ************************************************************/
+#define BL_HEAP_POINTER_FLAG_BITS 3
+
+typedef struct _BL_HEAP_POINTER
+{
+ union
+ {
+ struct
+ {
+ ULONG_PTR BufferFree : 1;
+ ULONG_PTR BufferOnHeap : 1;
+ ULONG_PTR NotUsed : 1;
+ ULONG_PTR BufferPointer : (sizeof(ULONG_PTR) - BL_HEAP_POINTER_FLAG_BITS);
+ };
+ PVOID P;
+ };
+} BL_HEAP_POINTER, *PBL_HEAP_POINTER;
+
+typedef struct _BL_FREE_HEAP_ENTRY
+{
+ BL_HEAP_POINTER BufferNext;
+ BL_HEAP_POINTER BufferPrevious;
+ BL_HEAP_POINTER FreeNext;
+ BL_HEAP_POINTER FreePrevious;
+} BL_FREE_HEAP_ENTRY, *PBL_FREE_HEAP_ENTRY;
+
+typedef struct _BL_BUSY_HEAP_ENTRY
+{
+ BL_HEAP_POINTER BufferNext;
+ BL_HEAP_POINTER BufferPrevious;
+ UCHAR Buffer[ANYSIZE_ARRAY];
+} BL_BUSY_HEAP_ENTRY, *PBL_BUSY_HEAP_ENTRY;
+
+typedef struct _BL_HEAP_BOUNDARIES
+{
+ LIST_ENTRY ListEntry;
+ ULONG_PTR HeapHigh;
+ ULONG_PTR HeapLimit;
+ ULONG_PTR HeapBottom;
+ PBL_BUSY_HEAP_ENTRY HeapTop;
+} BL_HEAP_BOUNDARIES, *PBL_HEAP_BOUNDARIES;
+
+ULONG HapInitializationStatus;
+LIST_ENTRY MmHeapBoundaries;
+ULONG HapMinimumHeapSize;
+ULONG HapAllocationAttributes;
+PBL_FREE_HEAP_ENTRY* MmFreeList;
/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+MmHapHeapAllocatorExtend (
+ _In_ ULONG ExtendSize
+ )
+{
+ ULONG HeapSize, AlignedSize, HeapLimit;
+ PBL_HEAP_BOUNDARIES Heap, NewHeap;
+ NTSTATUS Status;
+ PBL_BUSY_HEAP_ENTRY HeapBase = NULL;
+
+ /* Compute a new heap, and add 2 more pages for the free list */
+ HeapSize = ExtendSize + (2 * PAGE_SIZE);
+ if ((ExtendSize + (2 * PAGE_SIZE)) < ExtendSize)
+ {
+ return STATUS_INTEGER_OVERFLOW;
+ }
+
+ /* Make sure the new heap is at least the minimum configured size */
+ if (HapMinimumHeapSize > HeapSize)
+ {
+ HeapSize = HapMinimumHeapSize;
+ }
+
+ /* Align it on a page boundary */
+ AlignedSize = ALIGN_UP_BY(HeapSize, PAGE_SIZE);
+ if (!AlignedSize)
+ {
+ return STATUS_INTEGER_OVERFLOW;
+ }
+
+ /* Check if we already have a heap */
+ if (!IsListEmpty(&MmHeapBoundaries))
+ {
+ /* Find the first heap*/
+ Heap = CONTAINING_RECORD(MmHeapBoundaries.Flink,
+ BL_HEAP_BOUNDARIES,
+ ListEntry);
+
+ /* Check if we have a page free above the heap */
+ HeapLimit = Heap->HeapLimit + PAGE_SIZE;
+ if (HeapLimit <= Heap->HeapHigh)
+ {
+ EarlyPrint(L"TODO\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ /* We do not -- allocate one */
+ Status = MmPapAllocatePagesInRange((PULONG)&HeapBase,
+ BlLoaderHeap,
+ AlignedSize >> PAGE_SHIFT,
+ HapAllocationAttributes,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Set the heap bottom, limit, and top */
+ NewHeap = (PBL_HEAP_BOUNDARIES)HeapBase->Buffer;
+ NewHeap->HeapBottom = (ULONG_PTR)HeapBase;
+ NewHeap->HeapLimit = (ULONG_PTR)HeapBase + AlignedSize;
+ NewHeap->HeapTop = (PBL_BUSY_HEAP_ENTRY)(NewHeap + 1);
+
+ /* Set the buffer links */
+ HeapBase->BufferPrevious.P = NULL;
+ HeapBase->BufferNext.P = NewHeap->HeapTop;
+
+ /* Set the buffer at the top of the heap and mark it as being free */
+ NewHeap->HeapTop->BufferPrevious.P = HeapBase;
+ NewHeap->HeapTop->BufferNext.P = NewHeap->HeapTop;
+ NewHeap->HeapTop->BufferNext.BufferFree = 1;
+ NewHeap->HeapTop->BufferNext.BufferOnHeap = 1;
+
+ /* Is this the first heap ever? */
+ if (IsListEmpty(&MmHeapBoundaries))
+ {
+ /* We will host the free list at the top of the heap */
+ MmFreeList = (PBL_FREE_HEAP_ENTRY*)((ULONG_PTR)NewHeap->HeapLimit -
sizeof(BL_HEAP_BOUNDARIES));
+ NewHeap->HeapLimit = (ULONG_PTR)MmFreeList;
+ RtlZeroMemory(MmFreeList, 8 * sizeof(PBL_FREE_HEAP_ENTRY));
+ }
+
+ /* Remove a page on top */
+ HeapLimit = NewHeap->HeapLimit;
+ NewHeap->HeapHigh = NewHeap->HeapLimit;
+ NewHeap->HeapLimit -= PAGE_SIZE;
+
+ /* Add us into the heap list */
+ InsertTailList(&MmHeapBoundaries, &NewHeap->ListEntry);
+ return STATUS_SUCCESS;
+}
NTSTATUS
MmHaInitialize (
@@ -21,5 +162,27 @@
_In_ ULONG HeapAttributes
)
{
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ /* No free list to begin with */
+ MmFreeList = NULL;
+
+ /* Configure the minimum heap size and allocation attributes */
+ HapMinimumHeapSize = ALIGN_UP_BY(HeapSize, PAGE_SIZE);
+ HapAllocationAttributes = HeapAttributes & 0x20000;
+
+ /* Initialize the heap boundary list */
+ InitializeListHead(&MmHeapBoundaries);
+
+ /* Initialize a heap big enough to handle a one pointer long allocation */
+ Status = MmHapHeapAllocatorExtend(sizeof(PVOID));
+ if (NT_SUCCESS(Status))
+ {
+ /* The heap is ready! */
+ HapInitializationStatus = 1;
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Return initialization status */
+ return Status;
}
Modified: trunk/reactos/boot/environ/lib/mm/i386/mmx86.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/i386/m…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -12,15 +12,92 @@
/* DATA VARIABLES ************************************************************/
+ULONG_PTR MmArchKsegBase;
+ULONG_PTR MmArchKsegBias;
+ULONG MmArchLargePageSize;
+BL_ADDRESS_RANGE MmArchKsegAddressRange;
+ULONG_PTR MmArchTopOfApplicationAddressSpace;
+ULONG_PTR Mmx86SelfMapBase;
+
+typedef VOID
+(*PBL_MM_FLUSH_TLB) (
+ VOID
+ );
+
+typedef VOID
+(*PBL_MM_RELOCATE_SELF_MAP) (
+ VOID
+ );
+
+PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap;
+PBL_MM_FLUSH_TLB BlMmFlushTlb;
+
/* FUNCTIONS *****************************************************************/
+
+VOID
+MmArchNullFunction (
+ VOID
+ )
+{
+ /* Nothing to do */
+ return;
+}
NTSTATUS
MmArchInitialize (
_In_ ULONG Phase,
_In_ PBL_MEMORY_DATA MemoryData,
_In_ BL_TRANSLATION_TYPE TranslationType,
- _In_ BL_TRANSLATION_TYPE LibraryTranslationType
+ _In_ BL_TRANSLATION_TYPE RequestedTranslationType
)
{
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ /* For phase 2, just map deferred regions */
+ if (Phase != 1)
+ {
+ //return Mmx86pMapMemoryRegions(2, MemoryData);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* What translation type are we switching to? */
+ switch (RequestedTranslationType)
+ {
+ /* Physical memory */
+ case BlNone:
+
+ /* Initialize everything to default/null values */
+ MmArchLargePageSize = 1;
+ MmArchKsegBase = 0;
+ MmArchKsegBias = 0;
+ MmArchKsegAddressRange.Minimum = 0;
+ MmArchKsegAddressRange.Maximum = (ULONGLONG)~0;
+ MmArchTopOfApplicationAddressSpace = 0;
+ Mmx86SelfMapBase = 0;
+
+ /* Set stub functions */
+ BlMmRelocateSelfMap = MmArchNullFunction;
+ BlMmFlushTlb = MmArchNullFunction;
+
+ /* Set success */
+ Status = STATUS_SUCCESS;
+ break;
+
+ case BlVirtual:
+
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case BlPae:
+
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+
+ default:
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+
}
Modified: trunk/reactos/boot/environ/lib/mm/mm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/mm.c?r…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -22,9 +22,16 @@
VOID
)
{
+ /* Nothing to track if we're using physical memory */
+ if (MmTranslationType == BlNone)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* TODO */
+ EarlyPrint(L"Required for protected mode\n");
return STATUS_NOT_IMPLEMENTED;
}
-
NTSTATUS
BlMmRemoveBadMemory (
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun Sep 6 16:41:43 2015
@@ -43,6 +43,20 @@
}
NTSTATUS
+MmPapAllocatePagesInRange (
+ _Inout_ PULONG PhysicalAddress,
+ _In_ BL_MEMORY_TYPE MemoryType,
+ _In_ ULONGLONG Pages,
+ _In_ ULONG Attributes,
+ _In_ ULONG Alignment,
+ _In_opt_ PBL_ADDRESS_RANGE Range,
+ _In_ ULONG Type
+ )
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
MmPaInitialize (
__in PBL_MEMORY_DATA BootMemoryData,
__in ULONG MinimumAllocationCount
@@ -75,6 +89,7 @@
BL_MM_FLAG_REQUEST_COALESCING);
if (NT_SUCCESS(Status))
{
+#if 0
PLIST_ENTRY listHead, nextEntry;
/* Loop the NT firmware memory list */
@@ -93,6 +108,7 @@
nextEntry = nextEntry->Flink;
}
+#endif
/*
* Because BL supports cross x86-x64 application launches and a LIST_ENTRY
@@ -148,6 +164,7 @@
if (NT_SUCCESS(Status))
{
/* The Page Allocator has initialized */
+ EarlyPrint(L"Page Allocator initialized\n");
PapInitializationStatus = TRUE;
Status = STATUS_SUCCESS;
}