/* GLOBALS *******************************************************************/
+/* Share with Mm headers? */
+#define MM_HAL_VA_START (PVOID)0xFFC00000
+#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024))
+
BOOLEAN HalpPciLockSettings;
+ULONG HalpUsedAllocDescriptors;
+MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64];
+PVOID HalpHeapStart = MM_HAL_HEAP_START;
/* PRIVATE FUNCTIONS *********************************************************/
+ULONG
+NTAPI
+HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN ULONG MaxAddress,
+ IN ULONG PageCount,
+ IN BOOLEAN Aligned)
+{
+ ULONG UsedDescriptors, Alignment, PhysicalAddress;
+ PFN_NUMBER MaxPage, BasePage;
+ PLIST_ENTRY NextEntry;
+ PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;
+
+ /* Highest page we'll go */
+ MaxPage = MaxAddress >> PAGE_SHIFT;
+
+ /* We need at least two blocks */
+ if ((HalpUsedAllocDescriptors + 2) > 64) return 0;
+
+ /* Remember how many we have now */
+ UsedDescriptors = HalpUsedAllocDescriptors;
+
+ /* Loop the loader block memory descriptors */
+ NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+ while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
+ {
+ /* Get the block */
+ MdBlock = CONTAINING_RECORD(NextEntry,
+ MEMORY_ALLOCATION_DESCRIPTOR,
+ ListEntry);
+
+ /* No alignment by default */
+ Alignment = 0;
+
+ /* Unless requested, in which case we use a 64KB block alignment */
+ if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;
+
+ /* Search for free memory */
+ if ((MdBlock->MemoryType == LoaderFree) ||
+ (MdBlock->MemoryType == MemoryFirmwareTemporary))
+ {
+ /* Make sure the page is within bounds, including alignment */
+ BasePage = MdBlock->BasePage;
+ if ((BasePage) &&
+ (MdBlock->PageCount >= PageCount + Alignment) &&
+ (BasePage + PageCount + Alignment < MaxPage))
+ {
+
+ /* We found an address */
+ PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT;
+ break;
+ }
+ }
+
+ /* Keep trying */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* If we didn't find anything, get out of here */
+ if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;
+
+ /* Okay, now get a descriptor */
+ NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors];
+ NewBlock->PageCount = PageCount;
+ NewBlock->BasePage = MdBlock->BasePage + Alignment;
+ NewBlock->MemoryType = LoaderHALCachedMemory;
+
+ /* Update count */
+ UsedDescriptors++;
+ HalpUsedAllocDescriptors = UsedDescriptors;
+
+ /* Check if we had any alignment */
+ if (Alignment)
+ {
+ /* Check if we had leftovers */
+ if ((MdBlock->PageCount - Alignment) != PageCount)
+ {
+ /* Get the next descriptor */
+ FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
+ FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount;
+ FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount;
+
+ /* One more */
+ HalpUsedAllocDescriptors++;
+
+ /* Insert it into the list */
+ InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
+ }
+
+ /* Use this descriptor */
+ NewBlock->PageCount = Alignment;
+ InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
+ }
+ else
+ {
+ /* Consume memory from this block */
+ MdBlock->BasePage += PageCount;
+ MdBlock->PageCount -= PageCount;
+
+ /* Insert the descriptor */
+ InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);
+
+ /* Remove the entry if the whole block was allocated */
+ if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
+ }
+
+ /* Return the address */
+ return PhysicalAddress;
+}
+
+PVOID
+NTAPI
+HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN ULONG PageCount)
+{
+ PHARDWARE_PTE PointerPte;
+ ULONG 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 = 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 */
+ HalpFlushTLB();
+ return VirtualAddress;
+}
+
+VOID
+NTAPI
+HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
+ IN ULONG PageCount)
+{
+ PHARDWARE_PTE PointerPte;
+ ULONG i;
+
+ /* Only accept valid addresses */
+ if (VirtualAddress < 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 */
+ HalpFlushTLB();
+
+ /* Put the heap back */
+ if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress;
+}
+
VOID
NTAPI
HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, 1, 0);
}
+#ifndef _MINIHAL_
+ /* Initialize ACPI */
+ HalpSetupAcpiPhase0(LoaderBlock);
+
/* Initialize the PICs */
- HalpInitPICs();
+ HalpInitializePICs(TRUE);
+#endif
/* Force initial PIC state */
KfRaiseIrql(KeGetCurrentIrql());
- /* Initialize the clock */
- HalpInitializeClock();
+ /* Initialize CMOS lock */
+ KeInitializeSpinLock(&HalpSystemHardwareLock);
- /* Setup busy waiting */
- //HalpCalibrateStallExecution();
+ /* Initialize CMOS */
+ HalpInitializeCmos();
/* Fill out the dispatch tables */
HalQuerySystemInformation = HaliQuerySystemInformation;
HalSetSystemInformation = HaliSetSystemInformation;
HalInitPnpDriver = NULL; // FIXME: TODO
+#ifndef _MINIHAL_
HalGetDmaAdapter = HalpGetDmaAdapter;
+#else
+ HalGetDmaAdapter = NULL;
+#endif
HalGetInterruptTranslator = NULL; // FIXME: TODO
+#ifndef _MINIHAL_
HalResetDisplay = HalpBiosDisplayReset;
+#else
+ HalResetDisplay = NULL;
+#endif
+ HalHaltSystem = HaliHaltSystem;
- /* Initialize the hardware lock (CMOS) */
- KeInitializeSpinLock(&HalpSystemHardwareLock);
+ /* Register IRQ 2 */
+ HalpRegisterVector(IDT_INTERNAL,
+ PRIMARY_VECTOR_BASE + 2,
+ PRIMARY_VECTOR_BASE + 2,
+ HIGH_LEVEL);
+
+ /* Setup I/O space */
+ HalpDefaultIoSpace.Next = HalpAddressUsageList;
+ HalpAddressUsageList = &HalpDefaultIoSpace;
+
+ /* Setup busy waiting */
+ HalpCalibrateStallExecution();
+
+#ifndef _MINIHAL_
+ /* Initialize the clock */
+ HalpInitializeClock();
+#endif
+
+ /*
+ * We could be rebooting with a pending profile interrupt,
+ * so clear it here before interrupts are enabled
+ */
+ HalStopProfileInterrupt(ProfileTime);
/* Do some HAL-specific initialization */
HalpInitPhase0(LoaderBlock);
}
else if (BootPhase == 1)
{
- /* Initialize the default HAL stubs for bus handling functions */
- HalpInitNonBusHandler();
+ /* Initialize bus handlers */
+ HalpInitBusHandler();
- /* Enable the clock interrupt */
- ((PKIPCR)KeGetPcr())->IDT[0x30].ExtendedOffset =
- (USHORT)(((ULONG_PTR)HalpClockInterrupt >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[0x30].Offset =
- (USHORT)((ULONG_PTR)HalpClockInterrupt);
- HalEnableSystemInterrupt(0x30, CLOCK2_LEVEL, Latched);
+#ifndef _MINIHAL_
+ /* Enable IRQ 0 */
+ HalpEnableInterruptHandler(IDT_DEVICE,
+ 0,
+ PRIMARY_VECTOR_BASE,
+ CLOCK2_LEVEL,
+ HalpClockInterrupt,
+ Latched);
+
+ /* Enable IRQ 8 */
+ HalpEnableInterruptHandler(IDT_DEVICE,
+ 0,
+ PRIMARY_VECTOR_BASE + 8,
+ PROFILE_LEVEL,
+ HalpProfileInterrupt,
+ Latched);
/* Initialize DMA. NT does this in Phase 0 */
HalpInitDma();
+#endif
/* Do some HAL-specific initialization */
HalpInitPhase1();
/* All done, return */
return TRUE;
}
-
-/*
- * @unimplemented
- */
-VOID
-NTAPI
-HalReportResourceUsage(VOID)
-{
- /* Initialize PCI bus. */
- HalpInitializePciBus();
-
- /* FIXME: This is done in ReactOS MP HAL only*/
- //HaliReconfigurePciInterrupts();
-
- /* FIXME: Report HAL Usage to kernel */
-}
-
-/* EOF */