VOID NTAPI HalpUnmapRealModeMemory(VOID) { ULONG i; PHARDWARE_PTE Pte; // // Loop the first meg of memory // for (i = 0; i < 0x100000; i += PAGE_SIZE) { // // Invalidate each PTE // Pte = HalAddressToPte(i); Pte->Valid = 0; Pte->Write = 0; Pte->Owner = 0; Pte->PageFrameNumber = 0; } // // Restore the PDE for the lowest megabyte of memory // Pte = HalAddressToPde(0); *Pte = HalpSavedPte; Pte->PageFrameNumber = HalpSavedPfn; // // Flush the TLB // HalpFlushTLB(); }
VOID NTAPI HalpUnmapVirtualAddressVista(IN PVOID VirtualAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB) { PHARDWARE_PTE PointerPte; ULONG i; /* Only accept valid addresses */ if (VirtualAddress < (PVOID)MM_HAL_VA_START) return; /* Align it down to page size */ VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1)); /* Loop PTEs */ PointerPte = HalAddressToPte(VirtualAddress); for (i = 0; i < PageCount; i++) { *(PULONG)PointerPte = 0; PointerPte++; } /* Flush the TLB */ if (FlushCurrentTLB) HalpFlushTLB(); /* Put the heap back */ if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress; }
VOID NTAPI HalpMapRealModeMemory(VOID) { PHARDWARE_PTE Pte, V86Pte; ULONG i; // // Get the page table directory for the lowest meg of memory // Pte = HalAddressToPde(0); HalpSavedPfn = Pte->PageFrameNumber; HalpSavedPte = *Pte; // // Map it to the HAL reserved region and make it valid // Pte->Valid = 1; Pte->Write = 1; Pte->Owner = 1; Pte->PageFrameNumber = (HalAddressToPde(0xFFC00000))->PageFrameNumber; // // Flush the TLB // HalpFlushTLB(); // // Now loop the first meg of memory // for (i = 0; i < 0x100000; i += PAGE_SIZE) { // // Identity map it // Pte = HalAddressToPte(i); Pte->PageFrameNumber = i >> PAGE_SHIFT; Pte->Valid = 1; Pte->Write = 1; Pte->Owner = 1; } // // Now get the entry for our real mode V86 code and the target // Pte = HalAddressToPte(0x20000); V86Pte = HalAddressToPte(&HalpRealModeStart); do { // // Map the physical address into our real-mode region // Pte->PageFrameNumber = V86Pte->PageFrameNumber; // // Keep going until we've reached the end of our region // Pte++; V86Pte++; } while (V86Pte <= HalAddressToPte(&HalpRealModeEnd)); // // Flush the TLB // HalpFlushTLB(); }
PVOID NTAPI HalpMapPhysicalMemory64Vista(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB) { PHARDWARE_PTE PointerPte; PFN_NUMBER UsedPages = 0; PVOID VirtualAddress, BaseAddress; /* Start at the current HAL heap base */ BaseAddress = HalpHeapStart; VirtualAddress = BaseAddress; /* Loop until we have all the pages required */ while (UsedPages < PageCount) { /* If this overflows past the HAL heap, it means there's no space */ if (VirtualAddress == NULL) return NULL; /* Get the PTE for this address */ PointerPte = HalAddressToPte(VirtualAddress); /* Go to the next page */ VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); /* Check if the page is available */ if (PointerPte->Valid) { /* PTE has data, skip it and start with a new base address */ BaseAddress = VirtualAddress; UsedPages = 0; continue; } /* PTE is available, keep going on this run */ UsedPages++; } /* Take the base address of the page plus the actual offset in the address */ VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress + BYTE_OFFSET(PhysicalAddress.LowPart)); /* If we are starting at the heap, move the heap */ if (BaseAddress == HalpHeapStart) { /* Past this allocation */ HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE)); } /* Loop pages that can be mapped */ while (UsedPages--) { /* Fill out the PTE */ PointerPte = HalAddressToPte(BaseAddress); PointerPte->PageFrameNumber = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT); PointerPte->Valid = 1; PointerPte->Write = 1; /* Move to the next address */ PhysicalAddress.QuadPart += PAGE_SIZE; BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE); } /* Flush the TLB and return the address */ if (FlushCurrentTLB) HalpFlushTLB(); return VirtualAddress; }