3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/legacy/bussupp.c
5 * PURPOSE: HAL Legacy Bus Support Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 extern KSPIN_LOCK HalpPCIConfigLock
;
20 /* PRIVATE FUNCTIONS **********************************************************/
24 HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType
,
25 IN BUS_DATA_TYPE BusDataType
,
27 IN INTERFACE_TYPE ParentBusInterfaceType
,
28 IN ULONG ParentBusNumber
,
29 IN ULONG BusSpecificData
)
33 /* Register the bus handler */
34 HalRegisterBusHandler(InterfaceType
,
37 ParentBusInterfaceType
,
42 if (!Bus
) return NULL
;
44 /* Check for a valid interface */
45 if (InterfaceType
!= InterfaceTypeUndefined
)
47 /* Allocate address ranges and zero them out */
48 Bus
->BusAddresses
= ExAllocatePoolWithTag(NonPagedPool
,
49 sizeof(SUPPORTED_RANGES
),
51 RtlZeroMemory(Bus
->BusAddresses
, sizeof(SUPPORTED_RANGES
));
53 /* Build the data structure */
54 Bus
->BusAddresses
->Version
= HAL_SUPPORTED_RANGE_VERSION
;
55 Bus
->BusAddresses
->Dma
.Limit
= 7;
56 Bus
->BusAddresses
->Memory
.Limit
= 0xFFFFFFFF;
57 Bus
->BusAddresses
->IO
.Limit
= 0xFFFF;
58 Bus
->BusAddresses
->IO
.SystemAddressSpace
= 1;
59 Bus
->BusAddresses
->PrefetchMemory
.Base
= 1;
62 /* Return the bus address */
68 HalpRegisterInternalBusHandlers(VOID
)
72 /* Only do processor 1 */
73 if (KeGetCurrentPrcb()->Number
) return;
75 /* Register root support */
78 /* Allocate the system bus */
79 Bus
= HalpAllocateBusHandler(Internal
,
80 ConfigurationSpaceUndefined
,
82 InterfaceTypeUndefined
,
85 DPRINT1("Registering Internal Bus: %p\n", Bus
);
89 Bus
->GetInterruptVector
= HalpGetSystemInterruptVector
;
90 Bus
->TranslateBusAddress
= HalpTranslateSystemBusAddress
;
93 /* Allocate the CMOS bus */
94 Bus
= HalpAllocateBusHandler(InterfaceTypeUndefined
,
97 InterfaceTypeUndefined
,
100 DPRINT1("Registering CMOS Bus: %p\n", Bus
);
104 Bus
->GetBusData
= HalpcGetCmosData
;
105 Bus
->SetBusData
= HalpcSetCmosData
;
108 /* Allocate the CMOS bus */
109 Bus
= HalpAllocateBusHandler(InterfaceTypeUndefined
,
112 InterfaceTypeUndefined
,
115 DPRINT1("Registering CMOS Bus: %p\n", Bus
);
119 Bus
->GetBusData
= HalpcGetCmosData
;
120 Bus
->SetBusData
= HalpcSetCmosData
;
123 /* Allocate ISA bus */
124 Bus
= HalpAllocateBusHandler(Isa
,
125 ConfigurationSpaceUndefined
,
130 DPRINT1("Registering ISA Bus: %p\n", Bus
);
134 Bus
->GetBusData
= HalpNoBusData
;
135 Bus
->BusAddresses
->Memory
.Limit
= 0xFFFFFF;
136 Bus
->TranslateBusAddress
= HalpTranslateIsaBusAddress
;
139 /* No support for EISA or MCA */
140 ASSERT(HalpBusType
== MACHINE_TYPE_ISA
);
146 HalpMarkChipsetDecode(BOOLEAN OverrideEnable
)
149 UNICODE_STRING KeyString
;
150 ULONG Data
= OverrideEnable
;
151 HANDLE KeyHandle
, Handle
;
154 RtlInitUnicodeString(&KeyString
,
155 L
"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
156 Status
= HalpOpenRegistryKey(&Handle
, 0, &KeyString
, KEY_ALL_ACCESS
, FALSE
);
157 if (NT_SUCCESS(Status
))
159 /* Open PNP Bios key */
160 RtlInitUnicodeString(&KeyString
, L
"Control\\Biosinfo\\PNPBios");
161 Status
= HalpOpenRegistryKey(&KeyHandle
,
170 /* Check if PNP BIOS key exists */
171 if (NT_SUCCESS(Status
))
173 /* Set the override value */
174 RtlInitUnicodeString(&KeyString
, L
"FullDecodeChipsetOverride");
175 Status
= ZwSetValueKey(KeyHandle
,
193 HalpAllocateAndInitPciBusHandler(IN ULONG PciType
,
195 IN BOOLEAN TestAllocation
)
198 PPCIPBUSDATA BusData
;
200 /* Allocate the bus handler */
201 Bus
= HalpAllocateBusHandler(PCIBus
,
206 sizeof(PCIPBUSDATA
));
209 Bus
->GetBusData
= (PGETSETBUSDATA
)HalpGetPCIData
;
210 Bus
->SetBusData
= (PGETSETBUSDATA
)HalpSetPCIData
;
211 Bus
->GetInterruptVector
= (PGETINTERRUPTVECTOR
)HalpGetPCIIntOnISABus
;
212 Bus
->AdjustResourceList
= (PADJUSTRESOURCELIST
)HalpAdjustPCIResourceList
;
213 Bus
->AssignSlotResources
= (PASSIGNSLOTRESOURCES
)HalpAssignPCISlotResources
;
214 Bus
->BusAddresses
->Dma
.Limit
= 0;
216 /* Get our custom bus data */
217 BusData
= (PPCIPBUSDATA
)Bus
->BusData
;
219 /* Setup custom bus data */
220 BusData
->CommonData
.Tag
= PCI_DATA_TAG
;
221 BusData
->CommonData
.Version
= PCI_DATA_VERSION
;
222 BusData
->CommonData
.ReadConfig
= (PciReadWriteConfig
)HalpReadPCIConfig
;
223 BusData
->CommonData
.WriteConfig
= (PciReadWriteConfig
)HalpWritePCIConfig
;
224 BusData
->CommonData
.Pin2Line
= (PciPin2Line
)HalpPCIPin2ISALine
;
225 BusData
->CommonData
.Line2Pin
= (PciLine2Pin
)HalpPCIISALine2Pin
;
226 BusData
->MaxDevice
= PCI_MAX_DEVICES
;
227 BusData
->GetIrqRange
= (PciIrqRange
)HalpGetISAFixedPCIIrq
;
229 /* Initialize the bitmap */
230 RtlInitializeBitMap(&BusData
->DeviceConfigured
, BusData
->ConfiguredBits
, 256);
232 /* Check the type of PCI bus */
238 /* Copy the Type 1 handler data */
239 RtlCopyMemory(&PCIConfigHandler
,
240 &PCIConfigHandlerType1
,
241 sizeof(PCIConfigHandler
));
243 /* Set correct I/O Ports */
244 BusData
->Config
.Type1
.Address
= PCI_TYPE1_ADDRESS_PORT
;
245 BusData
->Config
.Type1
.Data
= PCI_TYPE1_DATA_PORT
;
251 /* Copy the Type 1 handler data */
252 RtlCopyMemory(&PCIConfigHandler
,
253 &PCIConfigHandlerType2
,
254 sizeof (PCIConfigHandler
));
256 /* Set correct I/O Ports */
257 BusData
->Config
.Type2
.CSE
= PCI_TYPE2_CSE_PORT
;
258 BusData
->Config
.Type2
.Forward
= PCI_TYPE2_FORWARD_PORT
;
259 BusData
->Config
.Type2
.Base
= PCI_TYPE2_ADDRESS_BASE
;
261 /* Only 16 devices supported, not 32 */
262 BusData
->MaxDevice
= 16;
268 DbgPrint("HAL: Unnkown PCI type\n");
271 /* Return the bus handler */
277 HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler
,
278 IN PCI_SLOT_NUMBER Slot
)
280 UCHAR DataBuffer
[PCI_COMMON_HDR_LENGTH
];
281 PPCI_COMMON_CONFIG PciHeader
= (PVOID
)DataBuffer
;
285 /* Read the PCI header */
286 HalpReadPCIConfig(BusHandler
, Slot
, PciHeader
, 0, PCI_COMMON_HDR_LENGTH
);
288 /* Make sure it's a valid device */
289 if ((PciHeader
->VendorID
== PCI_INVALID_VENDORID
) ||
290 (PCI_CONFIGURATION_TYPE(PciHeader
) != PCI_DEVICE_TYPE
))
296 /* Make sure interrupt numbers make sense */
297 if (((PciHeader
->u
.type0
.InterruptPin
) &&
298 (PciHeader
->u
.type0
.InterruptPin
> 4)) ||
299 (PciHeader
->u
.type0
.InterruptLine
& 0x70))
305 /* Now scan PCI BARs */
306 for (i
= 0; i
< PCI_TYPE0_ADDRESSES
; i
++)
308 /* Check what kind of address it is */
309 Address
= PciHeader
->u
.type0
.BaseAddresses
[i
];
310 if (Address
& PCI_ADDRESS_IO_SPACE
)
312 /* Highest I/O port is 65535 */
313 if (Address
> 0xFFFF) return FALSE
;
317 /* MMIO should be higher than 0x80000 */
318 if ((Address
> 0xF) && (Address
< 0x80000)) return FALSE
;
321 /* Is this a 64-bit address? */
322 if (!(Address
& PCI_ADDRESS_IO_SPACE
) &&
323 ((Address
& PCI_ADDRESS_MEMORY_TYPE_MASK
) == PCI_TYPE_64BIT
))
325 /* Check the next-next entry, since this one 64-bits wide */
330 /* Header, interrupt and address data all make sense */
334 static BOOLEAN WarningsGiven
[5];
338 HalpGetChipHacks(IN USHORT VendorId
,
343 UNICODE_STRING KeyName
, ValueName
;
345 OBJECT_ATTRIBUTES ObjectAttributes
;
348 KEY_VALUE_PARTIAL_INFORMATION PartialInfo
;
351 /* Setup the object attributes for the key */
352 RtlInitUnicodeString(&KeyName
,
353 L
"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\"
355 InitializeObjectAttributes(&ObjectAttributes
,
357 OBJ_CASE_INSENSITIVE
,
362 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &ObjectAttributes
);
363 if (!NT_SUCCESS(Status
)) return Status
;
366 swprintf(Buffer
, L
"%04X%04X", VendorId
, DeviceId
);
367 RtlInitUnicodeString(&ValueName
, Buffer
);
368 Status
= ZwQueryValueKey(KeyHandle
,
370 KeyValuePartialInformation
,
374 if (NT_SUCCESS(Status
))
376 /* Return the flags */
377 DPRINT1("Found HackFlags for your %lx:%lx device\n", VendorId
, DeviceId
);
378 *HackFlags
= *(PULONG
)PartialInfo
.Data
;
379 DPRINT1("Hack Flags: %lx (Hack Revision: %lx\tYour Revision: %lx)\n",
380 *HackFlags
, HALP_REVISION_FROM_HACK_FLAGS(*HackFlags
), RevisionId
);
382 /* Does it apply to this revision? */
383 if ((RevisionId
) && (RevisionId
>= (HALP_REVISION_FROM_HACK_FLAGS(*HackFlags
))))
385 /* Read the revision flags */
386 *HackFlags
= HALP_REVISION_HACK_FLAGS(*HackFlags
);
389 /* Throw out revision data */
390 *HackFlags
= HALP_HACK_FLAGS(*HackFlags
);
393 /* Close the handle and return */
400 HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo
,
401 IN PPCI_COMMON_CONFIG PciData
,
404 ULONG ElementCount
, i
;
405 PPCI_CARD_DESCRIPTOR CardDescriptor
;
407 /* How many PCI Cards that we know about? */
408 ElementCount
= PciRegistryInfo
->ElementCount
;
409 if (!ElementCount
) return FALSE
;
411 /* Loop all descriptors */
412 CardDescriptor
= &PciRegistryInfo
->CardList
[0];
413 for (i
= 0; i
< ElementCount
; i
++, CardDescriptor
++)
415 /* Check for flag match */
416 if (CardDescriptor
->Flags
!= Flags
) continue;
418 /* Check for VID-PID match */
419 if ((CardDescriptor
->VendorID
!= PciData
->VendorID
) ||
420 (CardDescriptor
->DeviceID
!= PciData
->DeviceID
))
426 /* Check for revision match, if requested */
427 if ((CardDescriptor
->Flags
& HALP_CHECK_CARD_REVISION_ID
) &&
428 (CardDescriptor
->RevisionID
!= PciData
->RevisionID
))
434 /* Check what kind of device this is */
435 switch (PCI_CONFIGURATION_TYPE(PciData
))
438 case PCI_CARDBUS_BRIDGE_TYPE
:
440 /* This means the real device header is in the device-specific data */
441 PciData
= (PPCI_COMMON_CONFIG
)PciData
->DeviceSpecific
;
443 /* Normal PCI device */
444 case PCI_DEVICE_TYPE
:
446 /* Check for subvendor match, if requested */
447 if ((CardDescriptor
->Flags
& HALP_CHECK_CARD_SUBVENDOR_ID
) &&
448 (CardDescriptor
->SubsystemVendorID
!= PciData
->u
.type0
.SubVendorID
))
454 /* Check for subsystem match, if requested */
455 if ((CardDescriptor
->Flags
& HALP_CHECK_CARD_SUBSYSTEM_ID
) &&
456 (CardDescriptor
->SubsystemID
!= PciData
->u
.type0
.SubSystemID
))
465 /* PCI Bridge -- don't bother */
466 case PCI_BRIDGE_TYPE
:
474 /* This means the card isn't recognized */
480 HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData
)
482 /* Simple test first */
483 if ((PciData
->BaseClass
== PCI_CLASS_MASS_STORAGE_CTLR
) &&
484 (PciData
->SubClass
== PCI_SUBCLASS_MSC_IDE_CTLR
))
486 /* The device is nice enough to admit it */
490 /* Symphony 82C101 */
491 if (PciData
->VendorID
== 0x1C1C) return TRUE
;
493 /* ALi MS4803 or M5219 */
494 if ((PciData
->VendorID
== 0x10B9) &&
495 ((PciData
->DeviceID
== 0x5215) || (PciData
->DeviceID
== 0x5219)))
500 /* Appian Technology */
501 if ((PciData
->VendorID
== 0x1097) && (PciData
->DeviceID
== 0x38)) return TRUE
;
503 /* Compaq Triflex Dual EIDE Controller */
504 if ((PciData
->VendorID
== 0xE11) && (PciData
->DeviceID
== 0xAE33)) return TRUE
;
506 /* Micron PC Tech RZ1000 */
507 if ((PciData
->VendorID
== 0x1042) && (PciData
->DeviceID
== 0x1000)) return TRUE
;
509 /* SiS 85C601 or 5513 [IDE] */
510 if ((PciData
->VendorID
== 0x1039) &&
511 ((PciData
->DeviceID
== 0x601) || (PciData
->DeviceID
== 0x5513)))
516 /* Symphony Labs W83769F */
517 if ((PciData
->VendorID
== 0x10AD) &&
518 ((PciData
->DeviceID
== 0x1) || (PciData
->DeviceID
== 0x150)))
524 if ((PciData
->VendorID
== 0x1060) && (PciData
->DeviceID
== 0x101)) return TRUE
;
526 /* You've survived */
532 HalpGetPciBridgeConfig(IN ULONG PciType
,
535 /* Not yet implemented */
536 if (!WarningsGiven
[2]++) DbgPrint("HAL: Not checking for PCI-to-PCI Bridges. Your hardware may malfunction!\n");
542 HalpFixupPciSupportedRanges(IN ULONG BusCount
)
545 PBUS_HANDLER Bus
, ParentBus
;
548 for (i
= 0; i
< BusCount
; i
++)
550 /* Get PCI bus handler */
551 Bus
= HalHandlerForBus(PCIBus
, i
);
553 /* Loop all parent buses */
554 ParentBus
= Bus
->ParentHandler
;
557 /* Should merge addresses */
558 if (!WarningsGiven
[0]++) DPRINT1("Found parent bus (indicating PCI Bridge). This is not supported!\n");
560 /* Check the next parent */
561 ParentBus
= ParentBus
->ParentHandler
;
565 /* Loop all buses again */
566 for (i
= 0; i
< BusCount
; i
++)
568 /* Get PCI bus handler */
569 Bus
= HalHandlerForBus(PCIBus
, i
);
571 /* Check if this is a PCI 2.2 Bus with Subtractive Decode */
572 if (!((PPCIPBUSDATA
)Bus
->BusData
)->Subtractive
)
574 /* Loop all parent buses */
575 ParentBus
= Bus
->ParentHandler
;
578 /* But check only PCI parent buses specifically */
579 if (ParentBus
->InterfaceType
== PCIBus
)
581 /* Should trim addresses */
582 if (!WarningsGiven
[1]++) DPRINT1("Found parent PCI Bus (indicating PCI-to-PCI Bridge). This is not supported!\n");
585 /* Check the next parent */
586 ParentBus
= ParentBus
->ParentHandler
;
591 /* Loop buses one last time */
592 for (i
= 0; i
< BusCount
; i
++)
594 /* Get the PCI bus handler */
595 Bus
= HalHandlerForBus(PCIBus
, i
);
597 /* Sort and combine (trim) bus address range information */
598 DPRINT("Warning: Bus addresses not being optimized!\n");
605 HalpInitializePciBus(VOID
)
608 PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo
;
610 PCI_SLOT_NUMBER PciSlot
;
612 UCHAR DataBuffer
[PCI_COMMON_HDR_LENGTH
];
613 PPCI_COMMON_CONFIG PciData
= (PPCI_COMMON_CONFIG
)DataBuffer
;
614 PBUS_HANDLER BusHandler
;
616 BOOLEAN ExtendedAddressDecoding
= FALSE
;
619 /* Query registry information */
620 PciRegistryInfo
= HalpQueryPciRegistryInfo();
621 if (!PciRegistryInfo
) return;
623 /* Initialize the PCI configuration lock */
624 KeInitializeSpinLock(&HalpPCIConfigLock
);
626 /* Get the type and free the info structure */
627 PciType
= PciRegistryInfo
->HardwareMechanism
& 0xF;
629 /* Check if this is a type 2 PCI bus with at least one bus */
630 if ((PciRegistryInfo
->NoBuses
) && (PciType
== 2))
632 /* Setup the PCI slot */
633 PciSlot
.u
.bits
.Reserved
= 0;
634 PciSlot
.u
.bits
.FunctionNumber
= 0;
637 for (i
= 0; i
< 32; i
++)
639 /* Try to setup a Type 2 PCI slot */
641 BusHandler
= HalpAllocateAndInitPciBusHandler(2, 0, TRUE
);
642 if (!BusHandler
) break;
644 /* Now check if it's valid */
645 if (HalpIsValidPCIDevice(BusHandler
, PciSlot
)) break;
647 /* Heh, the BIOS lied... try Type 1 */
649 BusHandler
= HalpAllocateAndInitPciBusHandler(1, 0, TRUE
);
650 if (!BusHandler
) break;
652 /* Now check if it's valid */
653 if (HalpIsValidPCIDevice(BusHandler
, PciSlot
)) break;
659 /* Now allocate the correct kind of handler */
660 HalpAllocateAndInitPciBusHandler(PciType
, 0, FALSE
);
663 /* Okay, now loop all PCI bridges */
666 /* Loop all PCI buses */
667 for (i
= 0; i
< PciRegistryInfo
->NoBuses
; i
++)
669 /* Check if we have a handler for it */
670 if (!HalHandlerForBus(PCIBus
, i
))
673 HalpAllocateAndInitPciBusHandler(PciType
, i
, FALSE
);
676 /* Go to the next bridge */
677 } while (HalpGetPciBridgeConfig(PciType
, &PciRegistryInfo
->NoBuses
));
679 /* Now build correct address range informaiton */
680 HalpFixupPciSupportedRanges(PciRegistryInfo
->NoBuses
);
683 PciSlot
.u
.bits
.Reserved
= 0;
684 for (i
= 0; i
< PciRegistryInfo
->NoBuses
; i
++)
686 /* Get the bus handler */
687 BusHandler
= HalHandlerForBus(PCIBus
, i
);
689 /* Loop every device */
690 for (j
= 0; j
< 32; j
++)
692 /* Loop every function */
693 PciSlot
.u
.bits
.DeviceNumber
= j
;
694 for (k
= 0; k
< 8; k
++)
696 /* Build the final slot structure */
697 PciSlot
.u
.bits
.FunctionNumber
= k
;
699 /* Read the configuration information */
700 HalpReadPCIConfig(BusHandler
,
704 PCI_COMMON_HDR_LENGTH
);
706 /* Skip if this is an invalid function */
707 if (PciData
->VendorID
== PCI_INVALID_VENDORID
) continue;
709 /* Check if this is a Cardbus bridge */
710 if (PCI_CONFIGURATION_TYPE(PciData
) == PCI_CARDBUS_BRIDGE_TYPE
)
713 DbgPrint("HAL: Your machine has a PCI Cardbus Bridge. This is not supported!\n");
717 /* Check if this is a PCI device */
718 if (PCI_CONFIGURATION_TYPE(PciData
) != PCI_BRIDGE_TYPE
)
720 /* Check if it has an interrupt pin and line registered */
721 if ((PciData
->u
.type1
.InterruptPin
) &&
722 (PciData
->u
.type1
.InterruptLine
))
724 /* Check if this interrupt line is connected to the bus */
725 if (PciData
->u
.type1
.InterruptLine
< 16)
727 /* Is this an IDE device? */
728 if (!HalpIsIdeDevice(PciData
))
730 /* We'll mask out this interrupt then */
731 DPRINT1("HAL: Device %lx:%lx is not an IDE Device. Should be masking IRQ %d! This is not supported!\n",
732 PciData
->VendorID
, PciData
->DeviceID
,
733 PciData
->u
.type1
.InterruptLine
);
734 HalpPciIrqMask
|= (1 << PciData
->u
.type1
.InterruptLine
);
740 /* Check for broken Intel chips */
741 if (PciData
->VendorID
== 0x8086)
743 /* Check for broken 82830 PCI controller */
744 if ((PciData
->DeviceID
== 0x04A3) &&
745 (PciData
->RevisionID
< 0x11))
748 DbgPrint("HAL: Your machine has a broken Intel 82430 PCI Controller. This is not supported!\n");
752 /* Check for broken 82378 PCI-to-ISA Bridge */
753 if ((PciData
->DeviceID
== 0x0484) &&
754 (PciData
->RevisionID
<= 3))
757 DbgPrint("HAL: Your machine has a broken Intel 82378 PCI-to-ISA Bridge. This is not supported!\n");
761 /* Check for broken 82450 PCI Bridge */
762 if ((PciData
->DeviceID
== 0x84C4) &&
763 (PciData
->RevisionID
<= 4))
765 DbgPrint("HAL: Your machine has an Intel Orion 82450 PCI Bridge. This is not supported!\n");
770 /* Do we know this card? */
771 if (!ExtendedAddressDecoding
)
774 if (HalpIsRecognizedCard(PciRegistryInfo
,
776 HALP_CARD_FEATURE_FULL_DECODE
))
778 /* We'll do chipset checks later */
779 DPRINT1("Your %lx:%lx PCI device has Extended Address Decoding. This is not supported!\n",
780 PciData
->VendorID
, PciData
->DeviceID
);
781 ExtendedAddressDecoding
= TRUE
;
785 /* Check if this is a USB controller */
786 if ((PciData
->BaseClass
== PCI_CLASS_SERIAL_BUS_CTLR
) &&
787 (PciData
->SubClass
== PCI_SUBCLASS_SB_USB
))
789 /* Check if this is an OHCI controller */
790 if (PciData
->ProgIf
== 0x10)
792 DbgPrint("HAL: Your machine has an OHCI (USB) PCI Expansion Card. This is not supported!\n");
796 /* Check for Intel UHCI controller */
797 if (PciData
->VendorID
== 0x8086)
799 DbgPrint("HAL: Your machine has an Intel UHCI (USB) Controller. This is not supported!\n");
803 /* Check for VIA UHCI controller */
804 if (PciData
->VendorID
== 0x1106)
806 DbgPrint("HAL: Your machine has a VIA UHCI (USB) Controller. This is not supported!\n");
811 /* Now check the registry for chipset hacks */
812 Status
= HalpGetChipHacks(PciData
->VendorID
,
816 if (NT_SUCCESS(Status
))
818 /* Check for broken ACPI routing */
819 if (HackFlags
& HAL_PCI_CHIP_HACK_DISABLE_ACPI_IRQ_ROUTING
)
821 DPRINT1("Your hardware has broken ACPI IRQ Routing! This is not supported!\n");
825 /* Check for broken ACPI timer */
826 if (HackFlags
& HAL_PCI_CHIP_HACK_BROKEN_ACPI_TIMER
)
828 DPRINT1("Your hardware has a broken ACPI timer! This is not supported!\n");
832 /* Check for hibernate-disable */
833 if (HackFlags
& HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE
)
835 DPRINT1("Your machine has a broken PCI device which is incompatible with hibernation. This is not supported!\n");
839 /* Check for USB controllers that generate SMIs */
840 if (HackFlags
& HAL_PCI_CHIP_HACK_USB_SMI_DISABLE
)
842 DPRINT1("Your machine has a USB controller which generates SMIs. This is not supported!\n");
850 /* Initialize NMI Crash Flag */
851 HalpGetNMICrashFlag();
853 /* Free the registry data */
854 ExFreePool(PciRegistryInfo
);
856 /* Tell PnP if this hard supports correct decoding */
857 HalpMarkChipsetDecode(ExtendedAddressDecoding
);
858 DPRINT1("PCI BUS Setup complete\n");
864 HalpInitBusHandlers(VOID
)
866 /* Register the HAL Bus Handler support */
867 HalpRegisterInternalBusHandlers();
872 HalpRegisterKdSupportFunctions(VOID
)
874 /* Register PCI Device Functions */
875 KdSetupPciDeviceForDebugging
= HalpSetupPciDeviceForDebugging
;
876 KdReleasePciDeviceforDebugging
= HalpReleasePciDeviceForDebugging
;
878 /* Register memory functions */
880 KdMapPhysicalMemory64
= HalpMapPhysicalMemory64
;
881 KdUnmapVirtualAddress
= HalpUnmapVirtualAddress
;
884 /* Register ACPI stub */
885 KdCheckPowerButton
= HalpCheckPowerButton
;
890 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
891 IN PUNICODE_STRING DriverClassName
,
892 IN PDRIVER_OBJECT DriverObject
,
893 IN PDEVICE_OBJECT DeviceObject
,
894 IN INTERFACE_TYPE BusType
,
897 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
899 BUS_HANDLER BusHandler
;
902 /* Only PCI is supported */
903 if (BusType
!= PCIBus
) return STATUS_NOT_IMPLEMENTED
;
905 /* Setup fake PCI Bus handler */
906 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
907 BusHandler
.BusNumber
= BusNumber
;
909 /* Call the PCI function */
910 return HalpAssignPCISlotResources(&BusHandler
,
922 HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
924 IN PHYSICAL_ADDRESS BusAddress
,
925 IN OUT PULONG AddressSpace
,
926 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
928 /* Translation is easy */
929 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
935 HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber
,
936 IN ULONG BusInterruptLevel
,
937 IN ULONG BusInterruptVector
,
939 OUT PKAFFINITY Affinity
)
941 ULONG Vector
= IRQ2VECTOR(BusInterruptLevel
);
942 *Irql
= (KIRQL
)VECTOR2IRQL(Vector
);
943 *Affinity
= 0xFFFFFFFF;
949 HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress
,
950 IN OUT PULONG AddressSpace
,
951 OUT PPHYSICAL_ADDRESS TranslatedAddress
,
952 IN OUT PULONG_PTR Context
,
955 /* Make sure we have a context */
956 if (!Context
) return FALSE
;
958 /* If we have data in the context, then this shouldn't be a new lookup */
959 if ((*Context
) && (NextBus
== TRUE
)) return FALSE
;
961 /* Return bus data */
962 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
964 /* Set context value and return success */
969 /* PUBLIC FUNCTIONS **********************************************************/
976 HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources
)
978 /* Deprecated, return success */
979 return STATUS_SUCCESS
;
987 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
988 IN PUNICODE_STRING DriverClassName
,
989 IN PDRIVER_OBJECT DriverObject
,
990 IN PDEVICE_OBJECT DeviceObject
,
991 IN INTERFACE_TYPE BusType
,
994 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
996 /* Check the bus type */
997 if (BusType
!= PCIBus
)
999 /* Call our internal handler */
1000 return HalpAssignSlotResources(RegistryPath
,
1007 AllocatedResources
);
1011 /* Call the PCI registered function */
1012 return HalPciAssignSlotResources(RegistryPath
,
1019 AllocatedResources
);
1028 HalGetBusData(IN BUS_DATA_TYPE BusDataType
,
1030 IN ULONG SlotNumber
,
1034 /* Call the extended function */
1035 return HalGetBusDataByOffset(BusDataType
,
1048 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType
,
1050 IN ULONG SlotNumber
,
1055 BUS_HANDLER BusHandler
;
1057 /* Look as the bus type */
1058 if (BusDataType
== Cmos
)
1060 /* Call CMOS Function */
1061 return HalpGetCmosData(0, SlotNumber
, Buffer
, Length
);
1063 else if (BusDataType
== EisaConfiguration
)
1068 else if ((BusDataType
== PCIConfiguration
) &&
1069 (HalpPCIConfigInitialized
) &&
1070 ((BusNumber
>= HalpMinPciBus
) && (BusNumber
<= HalpMaxPciBus
)))
1072 /* Setup fake PCI Bus handler */
1073 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
1074 BusHandler
.BusNumber
= BusNumber
;
1076 /* Call PCI function */
1077 return HalpGetPCIData(&BusHandler
,
1079 *(PPCI_SLOT_NUMBER
)&SlotNumber
,
1094 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType
,
1096 IN ULONG BusInterruptLevel
,
1097 IN ULONG BusInterruptVector
,
1099 OUT PKAFFINITY Affinity
)
1101 /* Call the system bus translator */
1102 return HalpGetSystemInterruptVector_Acpi(BusNumber
,
1114 HalSetBusData(IN BUS_DATA_TYPE BusDataType
,
1116 IN ULONG SlotNumber
,
1120 /* Call the extended function */
1121 return HalSetBusDataByOffset(BusDataType
,
1134 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType
,
1136 IN ULONG SlotNumber
,
1141 BUS_HANDLER BusHandler
;
1143 /* Look as the bus type */
1144 if (BusDataType
== Cmos
)
1146 /* Call CMOS Function */
1147 return HalpSetCmosData(0, SlotNumber
, Buffer
, Length
);
1149 else if ((BusDataType
== PCIConfiguration
) && (HalpPCIConfigInitialized
))
1151 /* Setup fake PCI Bus handler */
1152 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
1153 BusHandler
.BusNumber
= BusNumber
;
1155 /* Call PCI function */
1156 return HalpSetPCIData(&BusHandler
,
1158 *(PPCI_SLOT_NUMBER
)&SlotNumber
,
1173 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
1175 IN PHYSICAL_ADDRESS BusAddress
,
1176 IN OUT PULONG AddressSpace
,
1177 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
1179 /* Look as the bus type */
1180 if (InterfaceType
== PCIBus
)
1182 /* Call the PCI registered function */
1183 return HalPciTranslateBusAddress(PCIBus
,
1191 /* Translation is easy */
1192 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;