diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index e26ef18eb62..7eeb1ff8d41 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -1446,7 +1446,6 @@ MmFwGetMemoryMap ( /* Add 4 more descriptors just in case things changed */ EfiMemoryMapSize += (4 * DescriptorSize); Pages = BYTES_TO_PAGES(EfiMemoryMapSize); - EfiPrintf(L"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize, Pages); /* Should we use EFI to grab memory? */ if (UseEfiBuffer) diff --git a/reactos/boot/environ/lib/mm/i386/mmx86.c b/reactos/boot/environ/lib/mm/i386/mmx86.c index 5e1a68b1cad..630e9b23837 100644 --- a/reactos/boot/environ/lib/mm/i386/mmx86.c +++ b/reactos/boot/environ/lib/mm/i386/mmx86.c @@ -10,7 +10,16 @@ #include "bl.h" #include "bcd.h" -#include "../../../../../ntoskrnl/include/internal/i386/mm.h" + +#define PTE_BASE 0xC0000000 + +// +// Specific PDE/PTE macros to be used inside the boot library environment +// +#define MiAddressToPte(x) ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + (ULONG_PTR)MmPteBase)) +#define MiAddressToPde(x) ((PMMPDE)(((((ULONG)(x)) >> 22) << 2) + (ULONG_PTR)MmPdeBase)) +#define MiAddressToPteOffset(x) ((((ULONG)(x)) << 10) >> 22) +#define MiAddressToPdeOffset(x) (((ULONG)(x)) / (1024 * PAGE_SIZE)) /* DATA VARIABLES ************************************************************/ @@ -81,7 +90,7 @@ typedef NTSTATUS typedef NTSTATUS (*PBL_MM_MAP_PHYSICAL_ADDRESS) ( - _In_ PPHYSICAL_ADDRESS PhysicalAddress, + _In_ PHYSICAL_ADDRESS PhysicalAddress, _Out_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes @@ -111,6 +120,16 @@ PBL_MM_FLUSH_TLB Mmx86FlushTlb; /* FUNCTIONS *****************************************************************/ +BOOLEAN +BlMmIsTranslationEnabled ( + VOID + ) +{ + /* Return if paging is on */ + return ((CurrentExecutionContext) && + (CurrentExecutionContext->Mode & BL_CONTEXT_PAGING_ON)); +} + VOID MmArchNullFunction ( VOID @@ -277,14 +296,152 @@ MmDefpRemapVirtualAddress ( NTSTATUS MmDefpMapPhysicalAddress ( - _In_ PPHYSICAL_ADDRESS PhysicalAddress, - _Out_ PVOID VirtualAddress, + _In_ PHYSICAL_ADDRESS PhysicalAddress, + _In_ PVOID VirtualAddress, _In_ ULONG Size, _In_ ULONG CacheAttributes ) { - EfiPrintf(L"No map\r\n"); - return STATUS_NOT_IMPLEMENTED; + BOOLEAN Enabled; + ULONG i, PageCount, PdeOffset; + ULONGLONG CurrentAddress; + PMMPDE Pde; + PMMPTE Pte; + PMMPTE PageTable; + PHYSICAL_ADDRESS PageTableAddress; + NTSTATUS Status; + + /* Check if paging is on yet */ + Enabled = BlMmIsTranslationEnabled(); + + /* Get the physical address aligned */ + CurrentAddress = (PhysicalAddress.QuadPart >> PAGE_SHIFT) << PAGE_SHIFT; + + /* Get the number of pages and loop through each one */ + PageCount = Size >> PAGE_SHIFT; + for (i = 0; i < PageCount; i++) + { + /* Check if translation already exists for this page */ + if (Mmx86TranslateVirtualAddress(VirtualAddress, NULL, NULL)) + { + /* Ignore it and move to the next one */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + CurrentAddress += PAGE_SIZE; + continue; + } + + /* Get the PDE offset */ + PdeOffset = MiAddressToPdeOffset(VirtualAddress); + + /* Check if paging is actually turned on */ + if (Enabled) + { + /* Get the PDE entry using the self-map */ + Pde = MiAddressToPde(VirtualAddress); + } + else + { + /* Get it using our physical mappings */ + Pde = &MmPdpt[PdeOffset]; + PageTable = (PMMPDE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT); + } + + /* Check if we don't yet have a PDE */ + if (!Pde->u.Hard.Valid) + { + /* Allocate a page table */ + Status = MmPapAllocatePhysicalPagesInRange(&PageTableAddress, + BlLoaderPageDirectory, + 1, + 0, + 0, + &MmMdlUnmappedAllocated, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + return STATUS_NO_MEMORY; + } + + /* This is our page table */ + PageTable = (PVOID)(ULONG_PTR)PageTableAddress.QuadPart; + + /* Build the PDE for it */ + Pde->u.Hard.PageFrameNumber = PageTableAddress.QuadPart >> PAGE_SHIFT; + Pde->u.Hard.Write = 1; + Pde->u.Hard.CacheDisable = 1; + Pde->u.Hard.WriteThrough = 1; + Pde->u.Hard.Valid = 1; + + /* Check if paging is enabled */ + if (Enabled) + { + /* Then actually, get the page table's virtual address */ + PageTable = (PVOID)PAGE_ROUND_DOWN(MiAddressToPte(VirtualAddress)); + + /* Flush the TLB */ + Mmx86FlushTlb(); + } + + /* Zero out the page table */ + RtlZeroMemory(PageTable, PAGE_SIZE); + + /* Reset caching attributes now */ + Pde->u.Hard.CacheDisable = 0; + Pde->u.Hard.WriteThrough = 0; + + /* Check for paging again */ + if (Enabled) + { + /* Flush the TLB entry for the page table only */ + Mmx86FlushTlbEntry(PageTable); + } + } + + /* Add a reference to this page table */ + MmArchReferencePage[PdeOffset]++; + + /* Check if a physical address was given */ + if (PhysicalAddress.QuadPart != -1) + { + /* Check if paging is turned on */ + if (Enabled) + { + /* Get the PTE using the self-map */ + Pte = MiAddressToPte(VirtualAddress); + } + else + { + /* Get the PTE using physical addressing */ + Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)]; + } + + /* Build a valid PTE for it */ + Pte->u.Hard.PageFrameNumber = CurrentAddress >> PAGE_SHIFT; + Pte->u.Hard.Write = 1; + Pte->u.Hard.Valid = 1; + + /* Check if this is uncached */ + if (CacheAttributes == BlMemoryUncached) + { + /* Set the flags */ + Pte->u.Hard.CacheDisable = 1; + Pte->u.Hard.WriteThrough = 1; + } + else if (CacheAttributes == BlMemoryWriteThrough) + { + /* It's write-through, set the flag */ + Pte->u.Hard.WriteThrough = 1; + } + } + + /* Move to the next physical/virtual address */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + CurrentAddress += PAGE_SIZE; + } + + /* All done! */ + return STATUS_SUCCESS; } BOOLEAN @@ -294,8 +451,75 @@ MmDefpTranslateVirtualAddress ( _Out_opt_ PULONG CacheAttributes ) { - EfiPrintf(L"No translate\r\n"); - return FALSE; + PMMPDE Pde; + PMMPTE Pte; + PMMPTE PageTable; + BOOLEAN Enabled; + + /* Is there no page directory yet? */ + if (!MmPdpt) + { + return FALSE; + } + + /* Is paging enabled? */ + Enabled = BlMmIsTranslationEnabled(); + + /* Check if paging is actually turned on */ + if (Enabled) + { + /* Get the PDE entry using the self-map */ + Pde = MiAddressToPde(VirtualAddress); + } + else + { + /* Get it using our physical mappings */ + Pde = &MmPdpt[MiAddressToPdeOffset(VirtualAddress)]; + } + + /* Is the PDE valid? */ + if (!Pde->u.Hard.Valid) + { + return FALSE; + } + + /* Check if paging is turned on */ + if (Enabled) + { + /* Get the PTE using the self-map */ + Pte = MiAddressToPte(VirtualAddress); + } + else + { + /* Get the PTE using physical addressing */ + PageTable = (PMMPTE)(Pde->u.Hard.PageFrameNumber << PAGE_SHIFT); + Pte = &PageTable[MiAddressToPteOffset(VirtualAddress)]; + } + + /* Is the PTE valid? */ + if (!Pte->u.Hard.Valid) + { + return FALSE; + } + + /* Does caller want the physical address? */ + if (PhysicalAddress) + { + /* Return it */ + PhysicalAddress->QuadPart = (Pte->u.Hard.PageFrameNumber << PAGE_SHIFT) + + BYTE_OFFSET(VirtualAddress); + } + + /* Does caller want cache attributes? */ + if (CacheAttributes) + { + /* Not yet -- lie and say it's cached */ + EfiPrintf(L"Cache checking not yet enabled\r\n"); + *CacheAttributes = BlMemoryWriteBack; + } + + /* It exists! */ + return TRUE; } NTSTATUS @@ -323,16 +547,6 @@ MmSelectMappingAddress ( return STATUS_NOT_IMPLEMENTED; } -BOOLEAN -BlMmIsTranslationEnabled ( - VOID - ) -{ - /* Return if paging is on */ - return ((CurrentExecutionContext) && - (CurrentExecutionContext->Mode & BL_CONTEXT_PAGING_ON)); -} - NTSTATUS MmMapPhysicalAddress ( _Inout_ PPHYSICAL_ADDRESS PhysicalAddressPtr, @@ -419,7 +633,7 @@ MmMapPhysicalAddress ( /* Aactually do the mapping */ TranslatedAddress.QuadPart = PhysicalAddress; - Status = Mmx86MapPhysicalAddress(&TranslatedAddress, + Status = Mmx86MapPhysicalAddress(TranslatedAddress, VirtualAddress, Size, CacheAttributes); @@ -661,7 +875,7 @@ MmDefInitializeTranslation ( /* The PDE is the PTE of the PTE base */ MmPdeBase = MiAddressToPte(MmPteBase); - PdeIndex = MiGetPdeOffset(MmPdeBase); + PdeIndex = MiAddressToPdeOffset(MmPdeBase); MmPdpt[PdeIndex].u.Hard.Valid = 1; MmPdpt[PdeIndex].u.Hard.Write = 1; MmPdpt[PdeIndex].u.Hard.PageFrameNumber = (ULONG_PTR)MmPdpt >> PAGE_SHIFT; diff --git a/reactos/boot/environ/lib/mm/mm.c b/reactos/boot/environ/lib/mm/mm.c index 688ed8f5d19..832750b1d62 100644 --- a/reactos/boot/environ/lib/mm/mm.c +++ b/reactos/boot/environ/lib/mm/mm.c @@ -128,70 +128,6 @@ BlMmRemoveBadMemory ( return STATUS_SUCCESS; } -NTSTATUS -MmSelectMappingAddress ( - _Out_ PVOID* MappingAddress, - _In_ ULONGLONG Size, - _In_ ULONG AllocationAttributes, - _In_ ULONG Flags, - _In_ PHYSICAL_ADDRESS PhysicalAddress - ) -{ - /* Are we in physical mode? */ - if (MmTranslationType == BlNone) - { - /* Just return the physical address as the mapping address */ - *MappingAddress = (PVOID)PhysicalAddress.LowPart; - return STATUS_SUCCESS; - } - - /* We don't support virtual memory yet @TODO */ - EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__); - EfiStall(1000000); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -MmMapPhysicalAddress ( - _Inout_ PPHYSICAL_ADDRESS PhysicalAddress, - _Out_ PVOID VirtualAddress, - _Inout_ PULONGLONG Size, - _In_ ULONG CacheAttributes - ) -{ - ULONGLONG MappingSize; - - /* Fail if any parameters are missing */ - if (!(PhysicalAddress) || !(VirtualAddress) || !(Size)) - { - return STATUS_INVALID_PARAMETER; - } - - /* Fail if the size is over 32-bits */ - MappingSize = *Size; - if (MappingSize > 0xFFFFFFFF) - { - return STATUS_INVALID_PARAMETER; - } - - /* Nothing to do if we're in physical mode */ - if (MmTranslationType == BlNone) - { - return STATUS_SUCCESS; - } - - /* Can't use virtual memory in real mode */ - if (CurrentExecutionContext->Mode == BlRealMode) - { - return STATUS_UNSUCCESSFUL; - } - - /* We don't support virtual memory yet @TODO */ - EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__); - EfiStall(1000000); - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS BlMmMapPhysicalAddressEx ( _In_ PVOID* VirtualAddress, diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index 5644f11c9ea..16675b291ac 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -545,6 +545,7 @@ MmPaInitialize ( while (ExistingDescriptors != 0) { /* Remove this region from our free memory MDL */ + //EfiPrintf(L"Handling existing descriptor: %llx %llx\r\n", Descriptor->BasePage, Descriptor->PageCount); Status = MmMdRemoveRegionFromMdlEx(&MmMdlUnmappedUnallocated, BL_MM_REMOVE_PHYSICAL_REGION_FLAG, Descriptor->BasePage, @@ -743,7 +744,7 @@ MmPapFreePhysicalPages ( Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG; } - /* Check if the entire allocation is being free*/ + /* Check if the entire allocation is being freed */ if (PageCount == Descriptor->PageCount) { /* Remove the descriptor from the allocated list */