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?r... ============================================================================== --- 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/e... ============================================================================== --- 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/descrip... ============================================================================== --- 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/heapall... ============================================================================== --- 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/mm... ============================================================================== --- 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?re... ============================================================================== --- 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/pageall... ============================================================================== --- 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; }