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 HalpIsBridgeDevice(IN PPCI_COMMON_CONFIG PciData
)
534 /* Either this is a PCI-to-PCI Bridge, or a CardBUS Bridge */
535 return (((PCI_CONFIGURATION_TYPE(PciData
) == PCI_BRIDGE_TYPE
) &&
536 (PciData
->BaseClass
== PCI_CLASS_BRIDGE_DEV
) &&
537 (PciData
->SubClass
== PCI_SUBCLASS_BR_PCI_TO_PCI
)) ||
538 ((PCI_CONFIGURATION_TYPE(PciData
) == PCI_CARDBUS_BRIDGE_TYPE
) &&
539 (PciData
->BaseClass
== PCI_CLASS_BRIDGE_DEV
) &&
540 (PciData
->SubClass
== PCI_SUBCLASS_BR_CARDBUS
)));
545 HalpGetPciBridgeConfig(IN ULONG PciType
,
548 PCI_SLOT_NUMBER PciSlot
;
550 UCHAR DataBuffer
[PCI_COMMON_HDR_LENGTH
];
551 PPCI_COMMON_CONFIG PciData
= (PPCI_COMMON_CONFIG
)DataBuffer
;
552 PBUS_HANDLER BusHandler
;
555 PciSlot
.u
.bits
.Reserved
= 0;
556 for (i
= 0; i
< *BusCount
; i
++)
558 /* Get the bus handler */
559 BusHandler
= HalHandlerForBus(PCIBus
, i
);
561 /* Loop every device */
562 for (j
= 0; j
< PCI_MAX_DEVICES
; j
++)
564 /* Loop every function */
565 PciSlot
.u
.bits
.DeviceNumber
= j
;
566 for (k
= 0; k
< PCI_MAX_FUNCTION
; k
++)
568 /* Build the final slot structure */
569 PciSlot
.u
.bits
.FunctionNumber
= k
;
571 /* Read the configuration information */
572 HalpReadPCIConfig(BusHandler
,
576 PCI_COMMON_HDR_LENGTH
);
578 /* Skip if this is an invalid function */
579 if (PciData
->VendorID
== PCI_INVALID_VENDORID
) continue;
581 /* Make sure that this is a PCI bridge or a cardbus bridge */
582 if (!HalpIsBridgeDevice(PciData
)) continue;
585 if (!WarningsGiven
[2]++) DPRINT1("Your machine has a PCI-to-PCI or CardBUS Bridge. PCI devices may fail!\n");
591 /* If we exited the loop, then there's no bridge to worry about */
597 HalpFixupPciSupportedRanges(IN ULONG BusCount
)
600 PBUS_HANDLER Bus
, ParentBus
;
603 for (i
= 0; i
< BusCount
; i
++)
605 /* Get PCI bus handler */
606 Bus
= HalHandlerForBus(PCIBus
, i
);
608 /* Loop all parent buses */
609 ParentBus
= Bus
->ParentHandler
;
612 /* Should merge addresses */
613 if (!WarningsGiven
[0]++) DPRINT1("Found parent bus (indicating PCI Bridge). PCI devices may fail!\n");
615 /* Check the next parent */
616 ParentBus
= ParentBus
->ParentHandler
;
620 /* Loop all buses again */
621 for (i
= 0; i
< BusCount
; i
++)
623 /* Get PCI bus handler */
624 Bus
= HalHandlerForBus(PCIBus
, i
);
626 /* Check if this is a PCI 2.2 Bus with Subtractive Decode */
627 if (!((PPCIPBUSDATA
)Bus
->BusData
)->Subtractive
)
629 /* Loop all parent buses */
630 ParentBus
= Bus
->ParentHandler
;
633 /* But check only PCI parent buses specifically */
634 if (ParentBus
->InterfaceType
== PCIBus
)
636 /* Should trim addresses */
637 if (!WarningsGiven
[1]++) DPRINT1("Found parent PCI Bus (indicating PCI-to-PCI Bridge). PCI devices may fail!\n");
640 /* Check the next parent */
641 ParentBus
= ParentBus
->ParentHandler
;
646 /* Loop buses one last time */
647 for (i
= 0; i
< BusCount
; i
++)
649 /* Get the PCI bus handler */
650 Bus
= HalHandlerForBus(PCIBus
, i
);
652 /* Sort and combine (trim) bus address range information */
653 DPRINT("Warning: Bus addresses not being optimized!\n");
660 HalpInitializePciBus(VOID
)
663 PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo
;
665 PCI_SLOT_NUMBER PciSlot
;
667 UCHAR DataBuffer
[PCI_COMMON_HDR_LENGTH
];
668 PPCI_COMMON_CONFIG PciData
= (PPCI_COMMON_CONFIG
)DataBuffer
;
669 PBUS_HANDLER BusHandler
;
671 BOOLEAN ExtendedAddressDecoding
= FALSE
;
674 /* Query registry information */
675 PciRegistryInfo
= HalpQueryPciRegistryInfo();
676 if (!PciRegistryInfo
) return;
678 /* Initialize the PCI configuration lock */
679 KeInitializeSpinLock(&HalpPCIConfigLock
);
681 /* Get the type and free the info structure */
682 PciType
= PciRegistryInfo
->HardwareMechanism
& 0xF;
684 /* Check if this is a type 2 PCI bus with at least one bus */
685 if ((PciRegistryInfo
->NoBuses
) && (PciType
== 2))
687 /* Setup the PCI slot */
688 PciSlot
.u
.bits
.Reserved
= 0;
689 PciSlot
.u
.bits
.FunctionNumber
= 0;
692 for (i
= 0; i
< 32; i
++)
694 /* Try to setup a Type 2 PCI slot */
696 BusHandler
= HalpAllocateAndInitPciBusHandler(2, 0, TRUE
);
697 if (!BusHandler
) break;
699 /* Now check if it's valid */
700 if (HalpIsValidPCIDevice(BusHandler
, PciSlot
)) break;
702 /* Heh, the BIOS lied... try Type 1 */
704 BusHandler
= HalpAllocateAndInitPciBusHandler(1, 0, TRUE
);
705 if (!BusHandler
) break;
707 /* Now check if it's valid */
708 if (HalpIsValidPCIDevice(BusHandler
, PciSlot
)) break;
714 /* Now allocate the correct kind of handler */
715 HalpAllocateAndInitPciBusHandler(PciType
, 0, FALSE
);
718 /* Okay, now loop all PCI bridges */
721 /* Loop all PCI buses */
722 for (i
= 0; i
< PciRegistryInfo
->NoBuses
; i
++)
724 /* Check if we have a handler for it */
725 if (!HalHandlerForBus(PCIBus
, i
))
728 HalpAllocateAndInitPciBusHandler(PciType
, i
, FALSE
);
731 /* Go to the next bridge */
732 } while (HalpGetPciBridgeConfig(PciType
, &PciRegistryInfo
->NoBuses
));
734 /* Now build correct address range informaiton */
735 HalpFixupPciSupportedRanges(PciRegistryInfo
->NoBuses
);
738 PciSlot
.u
.bits
.Reserved
= 0;
739 for (i
= 0; i
< PciRegistryInfo
->NoBuses
; i
++)
741 /* Get the bus handler */
742 BusHandler
= HalHandlerForBus(PCIBus
, i
);
744 /* Loop every device */
745 for (j
= 0; j
< 32; j
++)
747 /* Loop every function */
748 PciSlot
.u
.bits
.DeviceNumber
= j
;
749 for (k
= 0; k
< 8; k
++)
751 /* Build the final slot structure */
752 PciSlot
.u
.bits
.FunctionNumber
= k
;
754 /* Read the configuration information */
755 HalpReadPCIConfig(BusHandler
,
759 PCI_COMMON_HDR_LENGTH
);
761 /* Skip if this is an invalid function */
762 if (PciData
->VendorID
== PCI_INVALID_VENDORID
) continue;
764 /* Check if this is a Cardbus bridge */
765 if (PCI_CONFIGURATION_TYPE(PciData
) == PCI_CARDBUS_BRIDGE_TYPE
)
768 DPRINT1("Your machine has a PCI Cardbus Bridge. This device will not work!\n");
772 /* Check if this is a PCI device */
773 if (PCI_CONFIGURATION_TYPE(PciData
) != PCI_BRIDGE_TYPE
)
775 /* Check if it has an interrupt pin and line registered */
776 if ((PciData
->u
.type1
.InterruptPin
) &&
777 (PciData
->u
.type1
.InterruptLine
))
779 /* Check if this interrupt line is connected to the bus */
780 if (PciData
->u
.type1
.InterruptLine
< 16)
782 /* Is this an IDE device? */
783 if (!HalpIsIdeDevice(PciData
))
785 /* We'll mask out this interrupt then */
786 DPRINT1("Device %lx:%lx is using IRQ %d! ISA Cards using that IRQ may fail!\n",
787 PciData
->VendorID
, PciData
->DeviceID
,
788 PciData
->u
.type1
.InterruptLine
);
789 HalpPciIrqMask
|= (1 << PciData
->u
.type1
.InterruptLine
);
795 /* Check for broken Intel chips */
796 if (PciData
->VendorID
== 0x8086)
798 /* Check for broken 82830 PCI controller */
799 if ((PciData
->DeviceID
== 0x04A3) &&
800 (PciData
->RevisionID
< 0x11))
803 DPRINT1("Your machine has a broken Intel 82430 PCI Controller. This device will not work!\n");
807 /* Check for broken 82378 PCI-to-ISA Bridge */
808 if ((PciData
->DeviceID
== 0x0484) &&
809 (PciData
->RevisionID
<= 3))
812 DPRINT1("Your machine has a broken Intel 82378 PCI-to-ISA Bridge. This device will not work!\n");
816 /* Check for broken 82450 PCI Bridge */
817 if ((PciData
->DeviceID
== 0x84C4) &&
818 (PciData
->RevisionID
<= 4))
820 DPRINT1("Your machine has an Intel Orion 82450 PCI Bridge. This device will not work!\n");
825 /* Do we know this card? */
826 if (!ExtendedAddressDecoding
)
829 if (HalpIsRecognizedCard(PciRegistryInfo
,
831 HALP_CARD_FEATURE_FULL_DECODE
))
833 /* We'll do chipset checks later */
834 DPRINT1("Your %lx:%lx PCI device has Extended Address Decoding. This device may fail to work on older BIOSes!\n",
835 PciData
->VendorID
, PciData
->DeviceID
);
836 ExtendedAddressDecoding
= TRUE
;
840 /* Check if this is a USB controller */
841 if ((PciData
->BaseClass
== PCI_CLASS_SERIAL_BUS_CTLR
) &&
842 (PciData
->SubClass
== PCI_SUBCLASS_SB_USB
))
844 /* Check if this is an OHCI controller */
845 if (PciData
->ProgIf
== 0x10)
847 DPRINT1("Your machine has an OHCI (USB) PCI Expansion Card. Turn off Legacy USB in your BIOS!\n");
851 /* Check for Intel UHCI controller */
852 if (PciData
->VendorID
== 0x8086)
854 DPRINT1("Your machine has an Intel UHCI (USB) Controller. Turn off Legacy USB in your BIOS!\n");
858 /* Check for VIA UHCI controller */
859 if (PciData
->VendorID
== 0x1106)
861 DPRINT1("Your machine has a VIA UHCI (USB) Controller. Turn off Legacy USB in your BIOS!\n");
866 /* Now check the registry for chipset hacks */
867 Status
= HalpGetChipHacks(PciData
->VendorID
,
871 if (NT_SUCCESS(Status
))
873 /* Check for broken ACPI routing */
874 if (HackFlags
& HAL_PCI_CHIP_HACK_DISABLE_ACPI_IRQ_ROUTING
)
876 DPRINT1("Your hardware has broken ACPI IRQ Routing! Be aware!\n");
880 /* Check for broken ACPI timer */
881 if (HackFlags
& HAL_PCI_CHIP_HACK_BROKEN_ACPI_TIMER
)
883 DPRINT1("Your hardware has a broken ACPI timer! Be aware!\n");
887 /* Check for hibernate-disable */
888 if (HackFlags
& HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE
)
890 DPRINT1("Your machine has a broken PCI device which is incompatible with hibernation. Be aware!\n");
894 /* Check for USB controllers that generate SMIs */
895 if (HackFlags
& HAL_PCI_CHIP_HACK_USB_SMI_DISABLE
)
897 DPRINT1("Your machine has a USB controller which generates SMIs. ReactOS will likely fail to boot!\n");
905 /* Initialize NMI Crash Flag */
906 HalpGetNMICrashFlag();
908 /* Free the registry data */
909 ExFreePool(PciRegistryInfo
);
911 /* Tell PnP if this hard supports correct decoding */
912 HalpMarkChipsetDecode(ExtendedAddressDecoding
);
913 DPRINT1("PCI BUS Setup complete\n");
919 HalpInitBusHandlers(VOID
)
921 /* Register the HAL Bus Handler support */
922 HalpRegisterInternalBusHandlers();
927 HalpRegisterKdSupportFunctions(VOID
)
929 /* Register PCI Device Functions */
930 KdSetupPciDeviceForDebugging
= HalpSetupPciDeviceForDebugging
;
931 KdReleasePciDeviceforDebugging
= HalpReleasePciDeviceForDebugging
;
933 /* Register memory functions */
935 KdMapPhysicalMemory64
= HalpMapPhysicalMemory64
;
936 KdUnmapVirtualAddress
= HalpUnmapVirtualAddress
;
939 /* Register ACPI stub */
940 KdCheckPowerButton
= HalpCheckPowerButton
;
945 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
946 IN PUNICODE_STRING DriverClassName
,
947 IN PDRIVER_OBJECT DriverObject
,
948 IN PDEVICE_OBJECT DeviceObject
,
949 IN INTERFACE_TYPE BusType
,
952 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
954 BUS_HANDLER BusHandler
;
957 /* Only PCI is supported */
958 if (BusType
!= PCIBus
) return STATUS_NOT_IMPLEMENTED
;
960 /* Setup fake PCI Bus handler */
961 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
962 BusHandler
.BusNumber
= BusNumber
;
964 /* Call the PCI function */
965 return HalpAssignPCISlotResources(&BusHandler
,
977 HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
979 IN PHYSICAL_ADDRESS BusAddress
,
980 IN OUT PULONG AddressSpace
,
981 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
983 /* Translation is easy */
984 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
990 HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber
,
991 IN ULONG BusInterruptLevel
,
992 IN ULONG BusInterruptVector
,
994 OUT PKAFFINITY Affinity
)
996 ULONG Vector
= IRQ2VECTOR(BusInterruptLevel
);
997 *Irql
= (KIRQL
)VECTOR2IRQL(Vector
);
998 *Affinity
= 0xFFFFFFFF;
1004 HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress
,
1005 IN OUT PULONG AddressSpace
,
1006 OUT PPHYSICAL_ADDRESS TranslatedAddress
,
1007 IN OUT PULONG_PTR Context
,
1010 /* Make sure we have a context */
1011 if (!Context
) return FALSE
;
1013 /* If we have data in the context, then this shouldn't be a new lookup */
1014 if ((*Context
) && (NextBus
== TRUE
)) return FALSE
;
1016 /* Return bus data */
1017 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
1019 /* Set context value and return success */
1024 /* PUBLIC FUNCTIONS **********************************************************/
1031 HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources
)
1033 /* Deprecated, return success */
1034 return STATUS_SUCCESS
;
1042 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
1043 IN PUNICODE_STRING DriverClassName
,
1044 IN PDRIVER_OBJECT DriverObject
,
1045 IN PDEVICE_OBJECT DeviceObject
,
1046 IN INTERFACE_TYPE BusType
,
1048 IN ULONG SlotNumber
,
1049 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
1051 /* Check the bus type */
1052 if (BusType
!= PCIBus
)
1054 /* Call our internal handler */
1055 return HalpAssignSlotResources(RegistryPath
,
1062 AllocatedResources
);
1066 /* Call the PCI registered function */
1067 return HalPciAssignSlotResources(RegistryPath
,
1074 AllocatedResources
);
1083 HalGetBusData(IN BUS_DATA_TYPE BusDataType
,
1085 IN ULONG SlotNumber
,
1089 /* Call the extended function */
1090 return HalGetBusDataByOffset(BusDataType
,
1103 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType
,
1105 IN ULONG SlotNumber
,
1110 BUS_HANDLER BusHandler
;
1112 /* Look as the bus type */
1113 if (BusDataType
== Cmos
)
1115 /* Call CMOS Function */
1116 return HalpGetCmosData(0, SlotNumber
, Buffer
, Length
);
1118 else if (BusDataType
== EisaConfiguration
)
1123 else if ((BusDataType
== PCIConfiguration
) &&
1124 (HalpPCIConfigInitialized
) &&
1125 ((BusNumber
>= HalpMinPciBus
) && (BusNumber
<= HalpMaxPciBus
)))
1127 /* Setup fake PCI Bus handler */
1128 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
1129 BusHandler
.BusNumber
= BusNumber
;
1131 /* Call PCI function */
1132 return HalpGetPCIData(&BusHandler
,
1134 *(PPCI_SLOT_NUMBER
)&SlotNumber
,
1149 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType
,
1151 IN ULONG BusInterruptLevel
,
1152 IN ULONG BusInterruptVector
,
1154 OUT PKAFFINITY Affinity
)
1156 /* Call the system bus translator */
1157 return HalpGetSystemInterruptVector_Acpi(BusNumber
,
1169 HalSetBusData(IN BUS_DATA_TYPE BusDataType
,
1171 IN ULONG SlotNumber
,
1175 /* Call the extended function */
1176 return HalSetBusDataByOffset(BusDataType
,
1189 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType
,
1191 IN ULONG SlotNumber
,
1196 BUS_HANDLER BusHandler
;
1198 /* Look as the bus type */
1199 if (BusDataType
== Cmos
)
1201 /* Call CMOS Function */
1202 return HalpSetCmosData(0, SlotNumber
, Buffer
, Length
);
1204 else if ((BusDataType
== PCIConfiguration
) && (HalpPCIConfigInitialized
))
1206 /* Setup fake PCI Bus handler */
1207 RtlCopyMemory(&BusHandler
, &HalpFakePciBusHandler
, sizeof(BUS_HANDLER
));
1208 BusHandler
.BusNumber
= BusNumber
;
1210 /* Call PCI function */
1211 return HalpSetPCIData(&BusHandler
,
1213 *(PPCI_SLOT_NUMBER
)&SlotNumber
,
1228 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
1230 IN PHYSICAL_ADDRESS BusAddress
,
1231 IN OUT PULONG AddressSpace
,
1232 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
1234 /* Look as the bus type */
1235 if (InterfaceType
== PCIBus
)
1237 /* Call the PCI registered function */
1238 return HalPciTranslateBusAddress(PCIBus
,
1246 /* Translation is easy */
1247 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;