diff --git a/hal/halx86/amd64/x86bios.c b/hal/halx86/amd64/x86bios.c index a8b7d94bc6c..a361196c6a4 100644 --- a/hal/halx86/amd64/x86bios.c +++ b/hal/halx86/amd64/x86bios.c @@ -14,15 +14,17 @@ #include -/* This page serves as fallback for pages used by Mm */ -#define DEFAULT_PAGE 0x21 - /* GLOBALS *******************************************************************/ +/* This page serves as fallback for pages used by Mm */ +PFN_NUMBER x86BiosFallbackPfn; + BOOLEAN x86BiosIsInitialized; LONG x86BiosBufferIsAllocated = 0; PUCHAR x86BiosMemoryMapping; +/* This the physical address of the bios buffer */ +ULONG64 x86BiosBufferPhysical; VOID NTAPI @@ -44,7 +46,7 @@ DbgDumpPage(PUCHAR MemBuffer, USHORT Segment) VOID NTAPI HalInitializeBios( - _In_ ULONG Unknown, + _In_ ULONG Phase, _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) { PPFN_NUMBER PfnArray; @@ -52,63 +54,97 @@ HalInitializeBios( PMEMORY_ALLOCATION_DESCRIPTOR Descriptor; PLIST_ENTRY ListEntry; PMDL Mdl; + ULONG64 PhysicalAddress; - /* Allocate an MDL for 1MB */ - Mdl = IoAllocateMdl(NULL, 0x100000, FALSE, FALSE, NULL); - if (!Mdl) + if (Phase == 0) { - ASSERT(FALSE); - } - - /* Get pointer to the pfn array */ - PfnArray = MmGetMdlPfnArray(Mdl); - - /* Fill the array with low memory PFNs */ - for (Pfn = 0; Pfn < 0x100; Pfn++) - { - PfnArray[Pfn] = Pfn; - } - - /* Loop the memory descriptors */ - for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - ListEntry != &LoaderBlock->MemoryDescriptorListHead; - ListEntry = ListEntry->Flink) - { - /* Get the memory descriptor */ - Descriptor = CONTAINING_RECORD(ListEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* Check if the memory is in the low range */ - if (Descriptor->BasePage < 0x100) + /* Allocate one page for a fallback mapping */ + PhysicalAddress = HalpAllocPhysicalMemory(LoaderBlock, + 0x100000, + 1, + FALSE); + if (PhysicalAddress == 0) { - /* Check if the memory type is firmware */ - if (Descriptor->MemoryType != LoaderFirmwarePermanent && - Descriptor->MemoryType != LoaderSpecialMemory) + ASSERT(FALSE); + } + + x86BiosFallbackPfn = PhysicalAddress / PAGE_SIZE; + ASSERT(x86BiosFallbackPfn != 0); + + /* Allocate a page for the buffer allocation */ + x86BiosBufferPhysical = HalpAllocPhysicalMemory(LoaderBlock, + 0x100000, + 1, + FALSE); + if (x86BiosBufferPhysical == 0) + { + ASSERT(FALSE); + } + } + else + { + + /* Allocate an MDL for 1MB */ + Mdl = IoAllocateMdl(NULL, 0x100000, FALSE, FALSE, NULL); + if (!Mdl) + { + ASSERT(FALSE); + } + + /* Get pointer to the pfn array */ + PfnArray = MmGetMdlPfnArray(Mdl); + + /* Fill the array with the fallback page */ + for (Pfn = 0; Pfn < 0x100; Pfn++) + { + PfnArray[Pfn] = x86BiosFallbackPfn; + } + + /* Loop the memory descriptors */ + for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + ListEntry != &LoaderBlock->MemoryDescriptorListHead; + ListEntry = ListEntry->Flink) + { + /* Get the memory descriptor */ + Descriptor = CONTAINING_RECORD(ListEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Check if the memory is in the low 1 MB range */ + if (Descriptor->BasePage < 0x100) { - /* It's something else, so don't use it! */ - Last = min(Descriptor->BasePage + Descriptor->PageCount, 0x100); - for (Pfn = Descriptor->BasePage; Pfn < Last; Pfn++) + /* Check if the memory type is firmware */ + if ((Descriptor->MemoryType == LoaderFirmwarePermanent) || + (Descriptor->MemoryType == LoaderSpecialMemory)) { - /* Set each page to the default page */ - PfnArray[Pfn] = DEFAULT_PAGE; + /* It's firmware, so map it! */ + Last = min(Descriptor->BasePage + Descriptor->PageCount, 0x100); + for (Pfn = Descriptor->BasePage; Pfn < Last; Pfn++) + { + /* Set each physical page in the MDL */ + PfnArray[Pfn] = Pfn; + } } } } + + /* Map this page proper, too */ + Pfn = x86BiosBufferPhysical / PAGE_SIZE; + PfnArray[Pfn] = Pfn; + + Mdl->MdlFlags = MDL_PAGES_LOCKED; + + /* Map the MDL to system space */ + x86BiosMemoryMapping = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority); + ASSERT(x86BiosMemoryMapping); + + DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8)); + //DbgDumpPage(x86BiosMemoryMapping, 0xc351); + + x86BiosIsInitialized = TRUE; + + HalpBiosDisplayReset(); } - - Mdl->MdlFlags = MDL_PAGES_LOCKED; - - /* Map the MDL to system space */ - x86BiosMemoryMapping = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority); - ASSERT(x86BiosMemoryMapping); - - DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8)); - //DbgDumpPage(x86BiosMemoryMapping, 0xc351); - - x86BiosIsInitialized = TRUE; - - HalpBiosDisplayReset(); } NTSTATUS @@ -134,7 +170,7 @@ x86BiosAllocateBuffer( /* The buffer is sufficient, return hardcoded address and size */ *Size = PAGE_SIZE; - *Segment = 0x2000; + *Segment = x86BiosBufferPhysical / 16; *Offset = 0; return STATUS_SUCCESS; @@ -291,7 +327,9 @@ ValidatePort( case 0x3B6: return (Size <= 2); } - return FALSE; + /* Allow but report unknown ports, we trust the BIOS for now */ + DPRINT1("Unknown port 0x%x, size %d, write %d\n", Port, Size, IsWrite); + return TRUE; } static diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c index 5b6ed2831b5..f918167cc61 100644 --- a/hal/halx86/generic/halinit.c +++ b/hal/halx86/generic/halinit.c @@ -136,6 +136,10 @@ HalInitSystem(IN ULONG BootPhase, /* Do some HAL-specific initialization */ HalpInitPhase0(LoaderBlock); + +#ifdef _M_AMD64 + HalInitializeBios(0, LoaderBlock); +#endif } else if (BootPhase == 1) { @@ -146,7 +150,7 @@ HalInitSystem(IN ULONG BootPhase, HalpInitPhase1(); #ifdef _M_AMD64 - HalInitializeBios(0, LoaderBlock); + HalInitializeBios(1, LoaderBlock); #endif } diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h index a93d4e517a9..080c0ac8462 100644 --- a/hal/halx86/include/halp.h +++ b/hal/halx86/include/halp.h @@ -534,7 +534,7 @@ extern ULONG PIT_FREQUENCY; VOID NTAPI HalInitializeBios( - _In_ ULONG Unknown, + _In_ ULONG Phase, _In_ PLOADER_PARAMETER_BLOCK LoaderBlock );