xref: /reactos/hal/halx86/legacy/bussupp.c (revision 6b700c6a)
1 /*
2  * PROJECT:         ReactOS HAL
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            hal/halx86/legacy/bussupp.c
5  * PURPOSE:         HAL Legacy Bus Support Code
6  * PROGRAMMERS:     ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
17 extern KSPIN_LOCK HalpPCIConfigLock;
18 ULONG HalpPciIrqMask;
19 
20 /* PRIVATE FUNCTIONS **********************************************************/
21 
22 PBUS_HANDLER
23 NTAPI
24 HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType,
25                        IN BUS_DATA_TYPE BusDataType,
26                        IN ULONG BusNumber,
27                        IN INTERFACE_TYPE ParentBusInterfaceType,
28                        IN ULONG ParentBusNumber,
29                        IN ULONG BusSpecificData)
30 {
31     PBUS_HANDLER Bus;
32 
33     /* Register the bus handler */
34     HalRegisterBusHandler(InterfaceType,
35                           BusDataType,
36                           BusNumber,
37                           ParentBusInterfaceType,
38                           ParentBusNumber,
39                           BusSpecificData,
40                           NULL,
41                           &Bus);
42     if (!Bus)
43     {
44         return NULL;
45     }
46 
47     /* Check for a valid interface */
48     if (InterfaceType != InterfaceTypeUndefined)
49     {
50         /* Allocate address ranges and zero them out */
51         Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
52                                                   sizeof(SUPPORTED_RANGES),
53                                                   TAG_HAL);
54         RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES));
55 
56         /* Build the data structure */
57         Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION;
58         Bus->BusAddresses->Dma.Limit = 7;
59         Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF;
60         Bus->BusAddresses->IO.Limit = 0xFFFF;
61         Bus->BusAddresses->IO.SystemAddressSpace = 1;
62         Bus->BusAddresses->PrefetchMemory.Base = 1;
63     }
64 
65     /* Return the bus address */
66     return Bus;
67 }
68 
69 CODE_SEG("INIT")
70 VOID
71 NTAPI
72 HalpRegisterInternalBusHandlers(VOID)
73 {
74     PBUS_HANDLER Bus;
75 
76     /* Only do processor 1 */
77     if (KeGetCurrentPrcb()->Number) return;
78 
79     /* Register root support */
80     HalpInitBusHandler();
81 
82     /* Allocate the system bus */
83     Bus = HalpAllocateBusHandler(Internal,
84                                  ConfigurationSpaceUndefined,
85                                  0,
86                                  InterfaceTypeUndefined,
87                                  0,
88                                  0);
89     if (Bus)
90     {
91         /* Set it up */
92         Bus->GetInterruptVector = HalpGetSystemInterruptVector;
93         Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
94     }
95 
96     /* Allocate the CMOS bus */
97     Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
98                                  Cmos,
99                                  0,
100                                  InterfaceTypeUndefined,
101                                  0,
102                                  0);
103     if (Bus)
104     {
105         /* Set it up */
106         Bus->GetBusData = HalpcGetCmosData;
107         Bus->SetBusData = HalpcSetCmosData;
108     }
109 
110     /* Allocate the CMOS bus */
111     Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
112                                  Cmos,
113                                  1,
114                                  InterfaceTypeUndefined,
115                                  0,
116                                  0);
117     if (Bus)
118     {
119         /* Set it up */
120         Bus->GetBusData = HalpcGetCmosData;
121         Bus->SetBusData = HalpcSetCmosData;
122     }
123 
124     /* Allocate ISA bus */
125     Bus = HalpAllocateBusHandler(Isa,
126                                  ConfigurationSpaceUndefined,
127                                  0,
128                                  Internal,
129                                  0,
130                                  0);
131     if (Bus)
132     {
133         /* Set it up */
134         Bus->GetBusData = HalpNoBusData;
135         Bus->BusAddresses->Memory.Limit = 0xFFFFFF;
136         Bus->TranslateBusAddress = HalpTranslateIsaBusAddress;
137     }
138 
139     /* No support for EISA or MCA */
140     ASSERT(HalpBusType == MACHINE_TYPE_ISA);
141 }
142 
143 #ifndef _MINIHAL_
144 CODE_SEG("INIT")
145 NTSTATUS
146 NTAPI
147 HalpMarkChipsetDecode(BOOLEAN OverrideEnable)
148 {
149     NTSTATUS Status;
150     UNICODE_STRING KeyString;
151     ULONG Data = OverrideEnable;
152     HANDLE KeyHandle, Handle;
153 
154     /* Open CCS key */
155     RtlInitUnicodeString(&KeyString,
156                          L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
157     Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
158     if (NT_SUCCESS(Status))
159     {
160         /* Open PNP Bios key */
161         RtlInitUnicodeString(&KeyString, L"Control\\Biosinfo\\PNPBios");
162         Status = HalpOpenRegistryKey(&KeyHandle,
163                                      Handle,
164                                      &KeyString,
165                                      KEY_ALL_ACCESS,
166                                      TRUE);
167 
168         /* Close root key */
169         ZwClose(Handle);
170 
171         /* Check if PNP BIOS key exists */
172         if (NT_SUCCESS(Status))
173         {
174             /* Set the override value */
175             RtlInitUnicodeString(&KeyString, L"FullDecodeChipsetOverride");
176             Status = ZwSetValueKey(KeyHandle,
177                                    &KeyString,
178                                    0,
179                                    REG_DWORD,
180                                    &Data,
181                                    sizeof(Data));
182 
183             /* Close subkey */
184             ZwClose(KeyHandle);
185         }
186     }
187 
188     /* Return status */
189     return Status;
190 }
191 
192 CODE_SEG("INIT")
193 PBUS_HANDLER
194 NTAPI
195 HalpAllocateAndInitPciBusHandler(IN ULONG PciType,
196                                  IN ULONG BusNo,
197                                  IN BOOLEAN TestAllocation)
198 {
199     PBUS_HANDLER Bus;
200     PPCIPBUSDATA BusData;
201 
202     /* Allocate the bus handler */
203     Bus = HalpAllocateBusHandler(PCIBus,
204                                  PCIConfiguration,
205                                  BusNo,
206                                  Internal,
207                                  0,
208                                  sizeof(PCIPBUSDATA));
209 
210     /* Set it up */
211     Bus->GetBusData = HalpGetPCIData;
212     Bus->SetBusData = HalpSetPCIData;
213     Bus->GetInterruptVector = HalpGetPCIIntOnISABus;
214     Bus->AdjustResourceList = HalpAdjustPCIResourceList;
215     Bus->AssignSlotResources = HalpAssignPCISlotResources;
216     Bus->BusAddresses->Dma.Limit = 0;
217 
218     /* Get our custom bus data */
219     BusData = (PPCIPBUSDATA)Bus->BusData;
220 
221     /* Setup custom bus data */
222     BusData->CommonData.Tag = PCI_DATA_TAG;
223     BusData->CommonData.Version = PCI_DATA_VERSION;
224     BusData->CommonData.ReadConfig = HalpReadPCIConfig;
225     BusData->CommonData.WriteConfig = HalpWritePCIConfig;
226     BusData->CommonData.Pin2Line = HalpPCIPin2ISALine;
227     BusData->CommonData.Line2Pin = HalpPCIISALine2Pin;
228     BusData->MaxDevice = PCI_MAX_DEVICES;
229     BusData->GetIrqRange = HalpGetISAFixedPCIIrq;
230 
231     /* Initialize the bitmap */
232     RtlInitializeBitMap(&BusData->DeviceConfigured, BusData->ConfiguredBits, 256);
233 
234     /* Check the type of PCI bus */
235     switch (PciType)
236     {
237         /* Type 1 PCI Bus */
238         case 1:
239 
240             /* Copy the Type 1 handler data */
241             RtlCopyMemory(&PCIConfigHandler,
242                           &PCIConfigHandlerType1,
243                           sizeof(PCIConfigHandler));
244 
245             /* Set correct I/O Ports */
246             BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT;
247             BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT;
248             break;
249 
250         /* Type 2 PCI Bus */
251         case 2:
252 
253             /* Copy the Type 1 handler data */
254             RtlCopyMemory(&PCIConfigHandler,
255                           &PCIConfigHandlerType2,
256                           sizeof (PCIConfigHandler));
257 
258             /* Set correct I/O Ports */
259             BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT;
260             BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT;
261             BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE;
262 
263             /* Only 16 devices supported, not 32 */
264             BusData->MaxDevice = 16;
265             break;
266 
267         default:
268 
269             /* Invalid type */
270             DbgPrint("HAL: Unnkown PCI type\n");
271     }
272 
273     /* Return the bus handler */
274     return Bus;
275 }
276 
277 CODE_SEG("INIT")
278 BOOLEAN
279 NTAPI
280 HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler,
281                      IN PCI_SLOT_NUMBER Slot)
282 {
283     UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
284     PPCI_COMMON_CONFIG PciHeader = (PVOID)DataBuffer;
285     ULONG i;
286     ULONG_PTR Address;
287 
288     /* Read the PCI header */
289     HalpReadPCIConfig(BusHandler, Slot, PciHeader, 0, PCI_COMMON_HDR_LENGTH);
290 
291     /* Make sure it's a valid device */
292     if ((PciHeader->VendorID == PCI_INVALID_VENDORID) ||
293         (PCI_CONFIGURATION_TYPE(PciHeader) != PCI_DEVICE_TYPE))
294     {
295         /* Bail out */
296         return FALSE;
297     }
298 
299     /* Make sure interrupt numbers make sense */
300     if (((PciHeader->u.type0.InterruptPin) &&
301          (PciHeader->u.type0.InterruptPin > 4)) ||
302         (PciHeader->u.type0.InterruptLine & 0x70))
303     {
304         /* Bail out */
305         return FALSE;
306     }
307 
308     /* Now scan PCI BARs */
309     for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
310     {
311         /* Check what kind of address it is */
312         Address = PciHeader->u.type0.BaseAddresses[i];
313         if (Address & PCI_ADDRESS_IO_SPACE)
314         {
315             /* Highest I/O port is 65535 */
316             if (Address > 0xFFFF) return FALSE;
317         }
318         else
319         {
320             /* MMIO should be higher than 0x80000 */
321             if ((Address > 0xF) && (Address < 0x80000)) return FALSE;
322         }
323 
324         /* Is this a 64-bit address? */
325         if (!(Address & PCI_ADDRESS_IO_SPACE) &&
326             ((Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT))
327         {
328             /* Check the next-next entry, since this one 64-bits wide */
329             i++;
330         }
331     }
332 
333     /* Header, interrupt and address data all make sense */
334     return TRUE;
335 }
336 
337 static BOOLEAN WarningsGiven[5];
338 
339 CODE_SEG("INIT")
340 NTSTATUS
341 NTAPI
342 HalpGetChipHacks(IN USHORT VendorId,
343                  IN USHORT DeviceId,
344                  IN UCHAR RevisionId,
345                  IN PULONG HackFlags)
346 {
347     UNICODE_STRING KeyName, ValueName;
348     NTSTATUS Status;
349     OBJECT_ATTRIBUTES ObjectAttributes;
350     HANDLE KeyHandle;
351     WCHAR Buffer[32];
352     KEY_VALUE_PARTIAL_INFORMATION PartialInfo;
353     ULONG ResultLength;
354 
355     /* Setup the object attributes for the key */
356     RtlInitUnicodeString(&KeyName,
357                          L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\"
358                          L"Control\\HAL");
359     InitializeObjectAttributes(&ObjectAttributes,
360                                &KeyName,
361                                OBJ_CASE_INSENSITIVE,
362                                NULL,
363                                NULL);
364 
365     /* Open the key */
366     Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
367     if (!NT_SUCCESS(Status)) return Status;
368 
369     /* Query value */
370     swprintf(Buffer, L"%04X%04X", VendorId, DeviceId);
371     RtlInitUnicodeString(&ValueName, Buffer);
372     Status = ZwQueryValueKey(KeyHandle,
373                              &ValueName,
374                              KeyValuePartialInformation,
375                              &PartialInfo,
376                              sizeof(PartialInfo),
377                              &ResultLength);
378     if (NT_SUCCESS(Status))
379     {
380         /* Return the flags */
381         DbgPrint("\tFound HackFlags for your chipset\n");
382         *HackFlags = *(PULONG)PartialInfo.Data;
383         DbgPrint("\t\tHack Flags: %lx (Hack Revision: %lx-Your Revision: %lx)\n",
384                  *HackFlags, HALP_REVISION_FROM_HACK_FLAGS(*HackFlags), RevisionId);
385 
386         /* Does it apply to this revision? */
387         if ((RevisionId) && (RevisionId >= (HALP_REVISION_FROM_HACK_FLAGS(*HackFlags))))
388         {
389             /* Read the revision flags */
390             *HackFlags = HALP_REVISION_HACK_FLAGS(*HackFlags);
391         }
392 
393         /* Throw out revision data */
394         *HackFlags = HALP_HACK_FLAGS(*HackFlags);
395         if (!*HackFlags) DbgPrint("\tNo HackFlags for your chipset's revision!\n");
396     }
397 
398     /* Close the handle and return */
399     ZwClose(KeyHandle);
400     return Status;
401 }
402 
403 CODE_SEG("INIT")
404 BOOLEAN
405 NTAPI
406 HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo,
407                      IN PPCI_COMMON_CONFIG PciData,
408                      IN ULONG Flags)
409 {
410     ULONG ElementCount, i;
411     PPCI_CARD_DESCRIPTOR CardDescriptor;
412 
413     /* How many PCI Cards that we know about? */
414     ElementCount = PciRegistryInfo->ElementCount;
415     if (!ElementCount) return FALSE;
416 
417     /* Loop all descriptors */
418     CardDescriptor = &PciRegistryInfo->CardList[0];
419     for (i = 0; i < ElementCount; i++, CardDescriptor++)
420     {
421         /* Check for flag match */
422         if (CardDescriptor->Flags != Flags) continue;
423 
424         /* Check for VID-PID match */
425         if ((CardDescriptor->VendorID != PciData->VendorID) ||
426             (CardDescriptor->DeviceID != PciData->DeviceID))
427         {
428             /* Skip */
429             continue;
430         }
431 
432         /* Check for revision match, if requested */
433         if ((CardDescriptor->Flags & HALP_CHECK_CARD_REVISION_ID) &&
434             (CardDescriptor->RevisionID != PciData->RevisionID))
435         {
436             /* Skip */
437             continue;
438         }
439 
440         /* Check what kind of device this is */
441         switch (PCI_CONFIGURATION_TYPE(PciData))
442         {
443             /* CardBUS Bridge */
444             case PCI_CARDBUS_BRIDGE_TYPE:
445 
446                 /* This means the real device header is in the device-specific data */
447                 PciData = (PPCI_COMMON_CONFIG)PciData->DeviceSpecific;
448 
449             /* Normal PCI device */
450             case PCI_DEVICE_TYPE:
451 
452                 /* Check for subvendor match, if requested */
453                 if ((CardDescriptor->Flags & HALP_CHECK_CARD_SUBVENDOR_ID) &&
454                     (CardDescriptor->SubsystemVendorID != PciData->u.type0.SubVendorID))
455                 {
456                     /* Skip */
457                     continue;
458                 }
459 
460                 /* Check for subsystem match, if requested */
461                 if ((CardDescriptor->Flags & HALP_CHECK_CARD_SUBSYSTEM_ID) &&
462                     (CardDescriptor->SubsystemID != PciData->u.type0.SubSystemID))
463                 {
464                     /* Skip */
465                     continue;
466                 }
467 
468                 /* You made it! */
469                 return TRUE;
470 
471             /* PCI Bridge -- don't bother */
472             case PCI_BRIDGE_TYPE:
473             default:
474 
475                 /* Recognize it */
476                 return TRUE;
477         }
478     }
479 
480     /* This means the card isn't recognized */
481     return FALSE;
482 }
483 
484 CODE_SEG("INIT")
485 BOOLEAN
486 NTAPI
487 HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData)
488 {
489     /* Simple test first */
490     if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
491         (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
492     {
493         /* The device is nice enough to admit it */
494         return TRUE;
495     }
496 
497     /* Symphony 82C101 */
498     if (PciData->VendorID == 0x1C1C) return TRUE;
499 
500     /* ALi MS4803 or M5219 */
501     if ((PciData->VendorID == 0x10B9) &&
502         ((PciData->DeviceID == 0x5215) || (PciData->DeviceID == 0x5219)))
503     {
504         return TRUE;
505     }
506 
507     /* Appian Technology */
508     if ((PciData->VendorID == 0x1097) && (PciData->DeviceID == 0x38)) return TRUE;
509 
510     /* Compaq Triflex Dual EIDE Controller */
511     if ((PciData->VendorID == 0xE11) && (PciData->DeviceID == 0xAE33)) return TRUE;
512 
513     /* Micron PC Tech RZ1000 */
514     if ((PciData->VendorID == 0x1042) && (PciData->DeviceID == 0x1000)) return TRUE;
515 
516     /* SiS 85C601 or 5513 [IDE] */
517     if ((PciData->VendorID == 0x1039) &&
518         ((PciData->DeviceID == 0x601) || (PciData->DeviceID == 0x5513)))
519     {
520         return TRUE;
521     }
522 
523     /* Symphony Labs W83769F */
524     if ((PciData->VendorID == 0x10AD) &&
525         ((PciData->DeviceID == 0x1) || (PciData->DeviceID == 0x150)))
526     {
527         return TRUE;
528     }
529 
530     /* UMC UM8673F */
531     if ((PciData->VendorID == 0x1060) && (PciData->DeviceID == 0x101)) return TRUE;
532 
533     /* You've survived */
534     return FALSE;
535 }
536 
537 CODE_SEG("INIT")
538 BOOLEAN
539 NTAPI
540 HalpIsBridgeDevice(IN PPCI_COMMON_CONFIG PciData)
541 {
542     /* Either this is a PCI-to-PCI Bridge, or a CardBUS Bridge */
543     return (((PCI_CONFIGURATION_TYPE(PciData) == PCI_BRIDGE_TYPE) &&
544              (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
545              (PciData->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI)) ||
546             ((PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE) &&
547              (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
548              (PciData->SubClass == PCI_SUBCLASS_BR_CARDBUS)));
549 }
550 
551 CODE_SEG("INIT")
552 BOOLEAN
553 NTAPI
554 HalpGetPciBridgeConfig(IN ULONG PciType,
555                        IN PUCHAR BusCount)
556 {
557     PCI_SLOT_NUMBER PciSlot;
558     ULONG i, j, k;
559     UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
560     PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer;
561     PBUS_HANDLER BusHandler;
562 
563     /* Loop PCI buses */
564     PciSlot.u.bits.Reserved = 0;
565     for (i = 0; i < *BusCount; i++)
566     {
567         /* Get the bus handler */
568         BusHandler = HalHandlerForBus(PCIBus, i);
569 
570         /* Loop every device */
571         for (j = 0; j < PCI_MAX_DEVICES; j++)
572         {
573             /* Loop every function */
574             PciSlot.u.bits.DeviceNumber = j;
575             for (k = 0; k < PCI_MAX_FUNCTION; k++)
576             {
577                 /* Build the final slot structure */
578                 PciSlot.u.bits.FunctionNumber = k;
579 
580                 /* Read the configuration information */
581                 HalpReadPCIConfig(BusHandler,
582                                   PciSlot,
583                                   PciData,
584                                   0,
585                                   PCI_COMMON_HDR_LENGTH);
586 
587                 /* Skip if this is an invalid function */
588                 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
589 
590                 /* Make sure that this is a PCI bridge or a cardbus bridge */
591                 if (!HalpIsBridgeDevice(PciData)) continue;
592 
593                 /* Not supported */
594                 if (!WarningsGiven[2]++) DPRINT1("Your machine has a PCI-to-PCI or CardBUS Bridge. PCI devices may fail!\n");
595                 continue;
596             }
597         }
598     }
599 
600     /* If we exited the loop, then there's no bridge to worry about */
601     return FALSE;
602 }
603 
604 CODE_SEG("INIT")
605 VOID
606 NTAPI
607 HalpFixupPciSupportedRanges(IN ULONG BusCount)
608 {
609     ULONG i;
610     PBUS_HANDLER Bus, ParentBus;
611 
612     /* Loop all buses */
613     for (i = 0; i < BusCount; i++)
614     {
615         /* Get PCI bus handler */
616         Bus = HalHandlerForBus(PCIBus, i);
617 
618         /* Loop all parent buses */
619         ParentBus = Bus->ParentHandler;
620         while (ParentBus)
621         {
622             /* Should merge addresses */
623             if (!WarningsGiven[0]++) DPRINT1("Found parent bus (indicating PCI Bridge). PCI devices may fail!\n");
624 
625             /* Check the next parent */
626             ParentBus = ParentBus->ParentHandler;
627         }
628     }
629 
630     /* Loop all buses again */
631     for (i = 0; i < BusCount; i++)
632     {
633         /* Get PCI bus handler */
634         Bus = HalHandlerForBus(PCIBus, i);
635 
636         /* Check if this is a PCI 2.2 Bus with Subtractive Decode */
637         if (!((PPCIPBUSDATA)Bus->BusData)->Subtractive)
638         {
639             /* Loop all parent buses */
640             ParentBus = Bus->ParentHandler;
641             while (ParentBus)
642             {
643                 /* But check only PCI parent buses specifically */
644                 if (ParentBus->InterfaceType == PCIBus)
645                 {
646                     /* Should trim addresses */
647                     if (!WarningsGiven[1]++) DPRINT1("Found parent PCI Bus (indicating PCI-to-PCI Bridge). PCI devices may fail!\n");
648                 }
649 
650                 /* Check the next parent */
651                 ParentBus = ParentBus->ParentHandler;
652             }
653         }
654     }
655 
656     /* Loop buses one last time */
657     for (i = 0; i < BusCount; i++)
658     {
659         /* Get the PCI bus handler */
660         Bus = HalHandlerForBus(PCIBus, i);
661 
662         /* Sort and combine (trim) bus address range information */
663         DPRINT("Warning: Bus addresses not being optimized!\n");
664     }
665 }
666 
667 CODE_SEG("INIT")
668 VOID
669 NTAPI
670 ShowSize(ULONG x)
671 {
672     if (!x) return;
673     DbgPrint(" [size=");
674     if (x < 1024)
675     {
676         DbgPrint("%d", (int) x);
677     }
678     else if (x < 1048576)
679     {
680         DbgPrint("%dK", (int)(x / 1024));
681     }
682     else if (x < 0x80000000)
683     {
684         DbgPrint("%dM", (int)(x / 1048576));
685     }
686     else
687     {
688         DbgPrint("%d", x);
689     }
690     DbgPrint("]");
691 }
692 
693 /*
694  * These includes are required to define
695  * the ClassTable and VendorTable arrays.
696  */
697 #include "pci_classes.h"
698 #include "pci_vendors.h"
699 CODE_SEG("INIT")
700 VOID
701 NTAPI
702 HalpDebugPciDumpBus(IN ULONG i,
703                     IN ULONG j,
704                     IN ULONG k,
705                     IN PPCI_COMMON_CONFIG PciData)
706 {
707     PCHAR p, ClassName, Boundary, SubClassName, VendorName, ProductName, SubVendorName;
708     ULONG Length;
709     CHAR LookupString[16] = "";
710     CHAR bSubClassName[64] = "Unknown";
711     CHAR bVendorName[64] = "";
712     CHAR bProductName[128] = "Unknown device";
713     CHAR bSubVendorName[128] = "Unknown";
714     ULONG Size, Mem, b;
715 
716     /* Isolate the class name */
717     sprintf(LookupString, "C %02x  ", PciData->BaseClass);
718     ClassName = strstr((PCHAR)ClassTable, LookupString);
719     if (ClassName)
720     {
721         /* Isolate the subclass name */
722         ClassName += strlen("C 00  ");
723         Boundary = strstr(ClassName, "\nC ");
724         sprintf(LookupString, "\n\t%02x  ", PciData->SubClass);
725         SubClassName = strstr(ClassName, LookupString);
726         if (Boundary && SubClassName > Boundary)
727         {
728             SubClassName = NULL;
729         }
730         if (!SubClassName)
731         {
732             SubClassName = ClassName;
733         }
734         else
735         {
736             SubClassName += strlen("\n\t00  ");
737         }
738         /* Copy the subclass into our buffer */
739         p = strpbrk(SubClassName, "\r\n");
740         Length = p - SubClassName;
741         if (Length >= sizeof(bSubClassName)) Length = sizeof(bSubClassName) - 1;
742         strncpy(bSubClassName, SubClassName, Length);
743         bSubClassName[Length] = '\0';
744     }
745 
746     /* Isolate the vendor name */
747     sprintf(LookupString, "\r\n%04x  ", PciData->VendorID);
748     VendorName = strstr((PCHAR)VendorTable, LookupString);
749     if (VendorName)
750     {
751         /* Copy the vendor name into our buffer */
752         VendorName += strlen("\r\n0000  ");
753         p = strpbrk(VendorName, "\r\n");
754         Length = p - VendorName;
755         if (Length >= sizeof(bVendorName)) Length = sizeof(bVendorName) - 1;
756         strncpy(bVendorName, VendorName, Length);
757         bVendorName[Length] = '\0';
758         p += strlen("\r\n");
759         while (*p == '\t' || *p == '#')
760         {
761             p = strpbrk(p, "\r\n");
762             p += strlen("\r\n");
763         }
764         Boundary = p;
765 
766         /* Isolate the product name */
767         sprintf(LookupString, "\t%04x  ", PciData->DeviceID);
768         ProductName = strstr(VendorName, LookupString);
769         if (Boundary && ProductName >= Boundary)
770         {
771             ProductName = NULL;
772         }
773         if (ProductName)
774         {
775             /* Copy the product name into our buffer */
776             ProductName += strlen("\t0000  ");
777             p = strpbrk(ProductName, "\r\n");
778             Length = p - ProductName;
779             if (Length >= sizeof(bProductName)) Length = sizeof(bProductName) - 1;
780             strncpy(bProductName, ProductName, Length);
781             bProductName[Length] = '\0';
782             p += strlen("\r\n");
783             while ((*p == '\t' && *(p + 1) == '\t') || *p == '#')
784             {
785                 p = strpbrk(p, "\r\n");
786                 p += strlen("\r\n");
787             }
788             Boundary = p;
789 
790             /* Isolate the subvendor and subsystem name */
791             sprintf(LookupString,
792                     "\t\t%04x %04x  ",
793                     PciData->u.type0.SubVendorID,
794                     PciData->u.type0.SubSystemID);
795             SubVendorName = strstr(ProductName, LookupString);
796             if (Boundary && SubVendorName >= Boundary)
797             {
798                 SubVendorName = NULL;
799             }
800             if (SubVendorName)
801             {
802                 /* Copy the subvendor name into our buffer */
803                 SubVendorName += strlen("\t\t0000 0000  ");
804                 p = strpbrk(SubVendorName, "\r\n");
805                 Length = p - SubVendorName;
806                 if (Length >= sizeof(bSubVendorName)) Length = sizeof(bSubVendorName) - 1;
807                 strncpy(bSubVendorName, SubVendorName, Length);
808                 bSubVendorName[Length] = '\0';
809             }
810         }
811     }
812 
813     /* Print out the data */
814     DbgPrint("%02x:%02x.%x %s [%02x%02x]: %s %s [%04x:%04x] (rev %02x)\n"
815              "\tSubsystem: %s [%04x:%04x]\n",
816              i,
817              j,
818              k,
819              bSubClassName,
820              PciData->BaseClass,
821              PciData->SubClass,
822              bVendorName,
823              bProductName,
824              PciData->VendorID,
825              PciData->DeviceID,
826              PciData->RevisionID,
827              bSubVendorName,
828              PciData->u.type0.SubVendorID,
829              PciData->u.type0.SubSystemID);
830 
831     /* Print out and decode flags */
832     DbgPrint("\tFlags:");
833     if (PciData->Command & PCI_ENABLE_BUS_MASTER) DbgPrint(" bus master,");
834     if (PciData->Status & PCI_STATUS_66MHZ_CAPABLE) DbgPrint(" 66MHz,");
835     if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x000) DbgPrint(" fast devsel,");
836     if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x200) DbgPrint(" medium devsel,");
837     if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x400) DbgPrint(" slow devsel,");
838     if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x600) DbgPrint(" unknown devsel,");
839     DbgPrint(" latency %d", PciData->LatencyTimer);
840     if (PciData->u.type0.InterruptPin != 0 &&
841         PciData->u.type0.InterruptLine != 0 &&
842         PciData->u.type0.InterruptLine != 0xFF) DbgPrint(", IRQ %02d", PciData->u.type0.InterruptLine);
843     else if (PciData->u.type0.InterruptPin != 0) DbgPrint(", IRQ assignment required");
844     DbgPrint("\n");
845 
846     /* Scan addresses */
847     Size = 0;
848     for (b = 0; b < PCI_TYPE0_ADDRESSES; b++)
849     {
850         /* Check for a BAR */
851         Mem = PciData->u.type0.BaseAddresses[b];
852         if (Mem)
853         {
854             /* Decode the address type */
855             if (Mem & PCI_ADDRESS_IO_SPACE)
856             {
857                 /* Guess the size */
858                 Size = 1 << 2;
859                 while (!(Mem & Size) && (Size)) Size <<= 1;
860 
861                 /* Print it out */
862                 DbgPrint("\tI/O ports at %04lx", Mem & PCI_ADDRESS_IO_ADDRESS_MASK);
863                 ShowSize(Size);
864             }
865             else
866             {
867                 /* Guess the size */
868                 Size = 1 << 8;
869                 while (!(Mem & Size) && (Size)) Size <<= 1;
870 
871                 /* Print it out */
872                 DbgPrint("\tMemory at %08lx (%d-bit, %sprefetchable)",
873                          Mem & PCI_ADDRESS_MEMORY_ADDRESS_MASK,
874                          (Mem & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_32BIT ? 32 : 64,
875                          (Mem & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? "" : "non-");
876                 ShowSize(Size);
877             }
878             DbgPrint("\n");
879         }
880     }
881 }
882 #endif
883 
884 CODE_SEG("INIT")
885 VOID
886 NTAPI
887 HalpInitializePciBus(VOID)
888 {
889 #ifndef _MINIHAL_
890     PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
891     UCHAR PciType;
892     PCI_SLOT_NUMBER PciSlot;
893     ULONG i, j, k;
894     UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
895     PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer;
896     PBUS_HANDLER BusHandler;
897     ULONG HackFlags;
898     BOOLEAN ExtendedAddressDecoding = FALSE;
899     NTSTATUS Status;
900 
901     /* Query registry information */
902     PciRegistryInfo = HalpQueryPciRegistryInfo();
903     if (!PciRegistryInfo) return;
904 
905     /* Initialize the PCI configuration lock */
906     KeInitializeSpinLock(&HalpPCIConfigLock);
907 
908     /* Get the type and free the info structure */
909     PciType = PciRegistryInfo->HardwareMechanism & 0xF;
910 
911     /* Check if this is a type 2 PCI bus with at least one bus */
912     if ((PciRegistryInfo->NoBuses) && (PciType == 2))
913     {
914         /* Setup the PCI slot */
915         PciSlot.u.bits.Reserved = 0;
916         PciSlot.u.bits.FunctionNumber = 0;
917 
918         /* Loop all slots */
919         for (i = 0; i < 32; i++)
920         {
921             /* Try to setup a Type 2 PCI slot */
922             PciType = 2;
923             BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE);
924             if (!BusHandler) break;
925 
926             /* Now check if it's valid */
927             if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;
928 
929             /* Heh, the BIOS lied... try Type 1 */
930             PciType = 1;
931             BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE);
932             if (!BusHandler) break;
933 
934             /* Now check if it's valid */
935             if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;
936 
937             /* Keep trying */
938             PciType = 2;
939         }
940 
941         /* Now allocate the correct kind of handler */
942         HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE);
943     }
944 
945     /* Okay, now loop all PCI bridges */
946     do
947     {
948         /* Loop all PCI buses */
949         for (i = 0; i < PciRegistryInfo->NoBuses; i++)
950         {
951             /* Check if we have a handler for it */
952             if (!HalHandlerForBus(PCIBus, i))
953             {
954                 /* Allocate it */
955                 HalpAllocateAndInitPciBusHandler(PciType, i, FALSE);
956             }
957         }
958         /* Go to the next bridge */
959     } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses));
960 
961     /* Now build correct address range informaiton */
962     HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses);
963 
964     /* Loop every bus */
965     DbgPrint("\n====== PCI BUS HARDWARE DETECTION =======\n\n");
966     PciSlot.u.bits.Reserved = 0;
967     for (i = 0; i < PciRegistryInfo->NoBuses; i++)
968     {
969         /* Get the bus handler */
970         BusHandler = HalHandlerForBus(PCIBus, i);
971 
972         /* Loop every device */
973         for (j = 0; j < 32; j++)
974         {
975             /* Loop every function */
976             PciSlot.u.bits.DeviceNumber = j;
977             for (k = 0; k < 8; k++)
978             {
979                 /* Build the final slot structure */
980                 PciSlot.u.bits.FunctionNumber = k;
981 
982                 /* Read the configuration information */
983                 HalpReadPCIConfig(BusHandler,
984                                   PciSlot,
985                                   PciData,
986                                   0,
987                                   PCI_COMMON_HDR_LENGTH);
988 
989                 /* Skip if this is an invalid function */
990                 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
991 
992                 /* Print out the entry */
993                 HalpDebugPciDumpBus(i, j, k, PciData);
994 
995                 /* Check if this is a Cardbus bridge */
996                 if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE)
997                 {
998                     /* Not supported */
999                     DbgPrint("\tDevice is a PCI Cardbus Bridge. It will not work!\n");
1000                     continue;
1001                 }
1002 
1003                 /* Check if this is a PCI device */
1004                 if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE)
1005                 {
1006                     /* Check if it has an interrupt pin and line registered */
1007                     if ((PciData->u.type1.InterruptPin) &&
1008                         (PciData->u.type1.InterruptLine))
1009                     {
1010                         /* Check if this interrupt line is connected to the bus */
1011                         if (PciData->u.type1.InterruptLine < 16)
1012                         {
1013                             /* Is this an IDE device? */
1014                             if (!HalpIsIdeDevice(PciData))
1015                             {
1016                                 /* We'll mask out this interrupt then */
1017                                 DbgPrint("\tDevice is using IRQ %d! ISA Cards using that IRQ may fail!\n",
1018                                          PciData->u.type1.InterruptLine);
1019                                 HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine);
1020                             }
1021                         }
1022                     }
1023                 }
1024 
1025                 /* Check for broken Intel chips */
1026                 if (PciData->VendorID == 0x8086)
1027                 {
1028                     /* Check for broken 82830 PCI controller */
1029                     if ((PciData->DeviceID == 0x04A3) &&
1030                         (PciData->RevisionID < 0x11))
1031                     {
1032                         /* Skip */
1033                         DbgPrint("\tDevice is a broken Intel 82430 PCI Controller. It will not work!\n\n");
1034                         continue;
1035                     }
1036 
1037                     /* Check for broken 82378 PCI-to-ISA Bridge */
1038                     if ((PciData->DeviceID == 0x0484) &&
1039                         (PciData->RevisionID <= 3))
1040                     {
1041                         /* Skip */
1042                         DbgPrint("\tDevice is a broken Intel 82378 PCI-to-ISA Bridge. It will not work!\n\n");
1043                         continue;
1044                     }
1045 
1046                     /* Check for broken 82450 PCI Bridge */
1047                     if ((PciData->DeviceID == 0x84C4) &&
1048                         (PciData->RevisionID <= 4))
1049                     {
1050                         DbgPrint("\tDevice is a Intel Orion 82450 PCI Bridge. It will not work!\n\n");
1051                         continue;
1052                     }
1053                 }
1054 
1055                 /* Do we know this card? */
1056                 if (!ExtendedAddressDecoding)
1057                 {
1058                     /* Check for it */
1059                     if (HalpIsRecognizedCard(PciRegistryInfo,
1060                                              PciData,
1061                                              HALP_CARD_FEATURE_FULL_DECODE))
1062                     {
1063                         /* We'll do chipset checks later */
1064                         DbgPrint("\tDevice has Extended Address Decoding. It may fail to work on older BIOSes!\n");
1065                         ExtendedAddressDecoding = TRUE;
1066                     }
1067                 }
1068 
1069                 /* Now check the registry for chipset hacks */
1070                 Status = HalpGetChipHacks(PciData->VendorID,
1071                                           PciData->DeviceID,
1072                                           PciData->RevisionID,
1073                                           &HackFlags);
1074                 if (NT_SUCCESS(Status))
1075                 {
1076                     /* Check for broken ACPI routing */
1077                     if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_ACPI_IRQ_ROUTING)
1078                     {
1079                         DbgPrint("This chipset has broken ACPI IRQ Routing! Be aware!\n\n");
1080                         continue;
1081                     }
1082 
1083                     /* Check for broken ACPI timer */
1084                     if (HackFlags & HAL_PCI_CHIP_HACK_BROKEN_ACPI_TIMER)
1085                     {
1086                          DbgPrint("This chipset has a broken ACPI timer! Be aware!\n\n");
1087                          continue;
1088                     }
1089 
1090                     /* Check for hibernate-disable */
1091                     if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE)
1092                     {
1093                         DbgPrint("This chipset has a broken PCI device which is incompatible with hibernation. Be aware!\n\n");
1094                         continue;
1095                     }
1096 
1097                     /* Check for USB controllers that generate SMIs */
1098                     if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE)
1099                     {
1100                         DbgPrint("This chipset has a USB controller which generates SMIs. ReactOS will likely fail to boot!\n\n");
1101                         continue;
1102                     }
1103                 }
1104 
1105                 /* Terminate the entry */
1106                 DbgPrint("\n");
1107             }
1108         }
1109     }
1110 
1111     /* Initialize NMI Crash Flag */
1112     HalpGetNMICrashFlag();
1113 
1114     /* Free the registry data */
1115     ExFreePoolWithTag(PciRegistryInfo, TAG_HAL);
1116 
1117     /* Tell PnP if this hard supports correct decoding */
1118     HalpMarkChipsetDecode(ExtendedAddressDecoding);
1119     DbgPrint("====== PCI BUS DETECTION COMPLETE =======\n\n");
1120 #endif
1121 }
1122 
1123 CODE_SEG("INIT")
1124 VOID
1125 NTAPI
1126 HalpInitBusHandlers(VOID)
1127 {
1128     /* Register the HAL Bus Handler support */
1129     HalpRegisterInternalBusHandlers();
1130 }
1131 
1132 CODE_SEG("INIT")
1133 VOID
1134 NTAPI
1135 HalpRegisterKdSupportFunctions(VOID)
1136 {
1137     /* Register PCI Device Functions */
1138     KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging;
1139     KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging;
1140 
1141     /* Register memory functions */
1142 #ifndef _MINIHAL_
1143 #if (NTDDI_VERSION >= NTDDI_VISTA)
1144     KdMapPhysicalMemory64 = HalpMapPhysicalMemory64Vista;
1145     KdUnmapVirtualAddress = HalpUnmapVirtualAddressVista;
1146 #else
1147     KdMapPhysicalMemory64 = HalpMapPhysicalMemory64;
1148     KdUnmapVirtualAddress = HalpUnmapVirtualAddress;
1149 #endif
1150 #endif
1151 
1152     /* Register ACPI stub */
1153     KdCheckPowerButton = HalpCheckPowerButton;
1154 }
1155 
1156 NTSTATUS
1157 NTAPI
1158 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath,
1159                         IN PUNICODE_STRING DriverClassName,
1160                         IN PDRIVER_OBJECT DriverObject,
1161                         IN PDEVICE_OBJECT DeviceObject,
1162                         IN INTERFACE_TYPE BusType,
1163                         IN ULONG BusNumber,
1164                         IN ULONG SlotNumber,
1165                         IN OUT PCM_RESOURCE_LIST *AllocatedResources)
1166 {
1167     PBUS_HANDLER Handler;
1168     NTSTATUS Status;
1169     PAGED_CODE();
1170     DPRINT1("Slot assignment for %d on bus %u\n", BusType, BusNumber);
1171 
1172     /* Find the handler */
1173     Handler = HalReferenceHandlerForBus(BusType, BusNumber);
1174     if (!Handler) return STATUS_NOT_FOUND;
1175 
1176     /* Do the assignment */
1177     Status = Handler->AssignSlotResources(Handler,
1178                                           Handler,
1179                                           RegistryPath,
1180                                           DriverClassName,
1181                                           DriverObject,
1182                                           DeviceObject,
1183                                           SlotNumber,
1184                                           AllocatedResources);
1185 
1186     /* Dereference the handler and return */
1187     HalDereferenceBusHandler(Handler);
1188     return Status;
1189 }
1190 
1191 BOOLEAN
1192 NTAPI
1193 HaliFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
1194                               IN OUT PULONG AddressSpace,
1195                               OUT PPHYSICAL_ADDRESS TranslatedAddress,
1196                               IN OUT PULONG_PTR Context,
1197                               IN BOOLEAN NextBus)
1198 {
1199     PHAL_BUS_HANDLER BusHandler;
1200     PBUS_HANDLER Handler;
1201     PLIST_ENTRY NextEntry;
1202     ULONG ContextValue;
1203 
1204     /* Make sure we have a context */
1205     if (!Context) return FALSE;
1206     ASSERT((*Context) || (NextBus == TRUE));
1207 
1208     /* Read the context */
1209     ContextValue = *Context;
1210 
1211     /* Find the bus handler */
1212     Handler = HalpContextToBusHandler(ContextValue);
1213     if (!Handler) return FALSE;
1214 
1215     /* Check if this is an ongoing lookup */
1216     if (NextBus)
1217     {
1218         /* Get the HAL bus handler */
1219         BusHandler = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler);
1220         NextEntry = &BusHandler->AllHandlers;
1221 
1222         /* Get the next one if we were already with one */
1223         if (ContextValue) NextEntry = NextEntry->Flink;
1224 
1225         /* Start scanning */
1226         while (TRUE)
1227         {
1228             /* Check if this is the last one */
1229             if (NextEntry == &HalpAllBusHandlers)
1230             {
1231                 /* Quit */
1232                 *Context = 1;
1233                 return FALSE;
1234             }
1235 
1236             /* Call this translator */
1237             BusHandler = CONTAINING_RECORD(NextEntry, HAL_BUS_HANDLER, AllHandlers);
1238             if (HalTranslateBusAddress(BusHandler->Handler.InterfaceType,
1239                                        BusHandler->Handler.BusNumber,
1240                                        BusAddress,
1241                                        AddressSpace,
1242                                        TranslatedAddress)) break;
1243 
1244             /* Try the next one */
1245             NextEntry = NextEntry->Flink;
1246         }
1247 
1248         /* If we made it, we're done */
1249         *Context = (ULONG_PTR)&BusHandler->Handler;
1250         return TRUE;
1251     }
1252 
1253     /* Try the first one through */
1254     if (!HalTranslateBusAddress(Handler->InterfaceType,
1255                                 Handler->BusNumber,
1256                                 BusAddress,
1257                                 AddressSpace,
1258                                 TranslatedAddress)) return FALSE;
1259 
1260     /* Remember for next time */
1261     *Context = (ULONG_PTR)Handler;
1262     return TRUE;
1263 }
1264 
1265 BOOLEAN
1266 NTAPI
1267 HaliTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
1268                         IN ULONG BusNumber,
1269                         IN PHYSICAL_ADDRESS BusAddress,
1270                         IN OUT PULONG AddressSpace,
1271                         OUT PPHYSICAL_ADDRESS TranslatedAddress)
1272 {
1273     PBUS_HANDLER Handler;
1274     BOOLEAN Status;
1275 
1276     /* Find the handler */
1277     Handler = HalReferenceHandlerForBus(InterfaceType, BusNumber);
1278     if (!(Handler) || !(Handler->TranslateBusAddress))
1279     {
1280         DPRINT1("No translator Interface: %x, Bus: %x, Handler: %p, BusAddress: %x!\n", InterfaceType, BusNumber, Handler, BusAddress);
1281         return FALSE;
1282     }
1283 
1284     /* Do the assignment */
1285     Status = Handler->TranslateBusAddress(Handler,
1286                                           Handler,
1287                                           BusAddress,
1288                                           AddressSpace,
1289                                           TranslatedAddress);
1290 
1291     /* Dereference the handler and return */
1292     HalDereferenceBusHandler(Handler);
1293     return Status;
1294 }
1295 
1296 /* PUBLIC FUNCTIONS **********************************************************/
1297 
1298 /*
1299  * @implemented
1300  */
1301 NTSTATUS
1302 NTAPI
1303 HalAdjustResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST *ResourceList)
1304 {
1305     PBUS_HANDLER Handler;
1306     ULONG Status;
1307     PAGED_CODE();
1308 
1309     /* Find the handler */
1310     Handler = HalReferenceHandlerForBus((*ResourceList)->InterfaceType,
1311                                         (*ResourceList)->BusNumber);
1312     if (!Handler) return STATUS_SUCCESS;
1313 
1314     /* Do the assignment */
1315     Status = Handler->AdjustResourceList(Handler,
1316                                          Handler,
1317                                          ResourceList);
1318 
1319     /* Dereference the handler and return */
1320     HalDereferenceBusHandler(Handler);
1321     return Status;
1322 }
1323 
1324 /*
1325  * @implemented
1326  */
1327 NTSTATUS
1328 NTAPI
1329 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath,
1330                        IN PUNICODE_STRING DriverClassName,
1331                        IN PDRIVER_OBJECT DriverObject,
1332                        IN PDEVICE_OBJECT DeviceObject,
1333                        IN INTERFACE_TYPE BusType,
1334                        IN ULONG BusNumber,
1335                        IN ULONG SlotNumber,
1336                        IN OUT PCM_RESOURCE_LIST *AllocatedResources)
1337 {
1338     PAGED_CODE();
1339 
1340     /* Check the bus type */
1341     if (BusType != PCIBus)
1342     {
1343         /* Call our internal handler */
1344         return HalpAssignSlotResources(RegistryPath,
1345                                        DriverClassName,
1346                                        DriverObject,
1347                                        DeviceObject,
1348                                        BusType,
1349                                        BusNumber,
1350                                        SlotNumber,
1351                                        AllocatedResources);
1352     }
1353     else
1354     {
1355         /* Call the PCI registered function */
1356         return HalPciAssignSlotResources(RegistryPath,
1357                                          DriverClassName,
1358                                          DriverObject,
1359                                          DeviceObject,
1360                                          PCIBus,
1361                                          BusNumber,
1362                                          SlotNumber,
1363                                          AllocatedResources);
1364     }
1365 }
1366 
1367 /*
1368  * @implemented
1369  */
1370 ULONG
1371 NTAPI
1372 HalGetBusData(IN BUS_DATA_TYPE BusDataType,
1373               IN ULONG BusNumber,
1374               IN ULONG SlotNumber,
1375               IN PVOID Buffer,
1376               IN ULONG Length)
1377 {
1378     /* Call the extended function */
1379     return HalGetBusDataByOffset(BusDataType,
1380                                  BusNumber,
1381                                  SlotNumber,
1382                                  Buffer,
1383                                  0,
1384                                  Length);
1385 }
1386 
1387 /*
1388  * @implemented
1389  */
1390 ULONG
1391 NTAPI
1392 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
1393                       IN ULONG BusNumber,
1394                       IN ULONG SlotNumber,
1395                       IN PVOID Buffer,
1396                       IN ULONG Offset,
1397                       IN ULONG Length)
1398 {
1399     PBUS_HANDLER Handler;
1400     ULONG Status;
1401 
1402     /* Find the handler */
1403     Handler = HaliReferenceHandlerForConfigSpace(BusDataType, BusNumber);
1404     if (!Handler) return 0;
1405 
1406     /* Do the assignment */
1407     Status = Handler->GetBusData(Handler,
1408                                  Handler,
1409                                  SlotNumber,
1410                                  Buffer,
1411                                  Offset,
1412                                  Length);
1413 
1414     /* Dereference the handler and return */
1415     HalDereferenceBusHandler(Handler);
1416     return Status;
1417 }
1418 
1419 /*
1420  * @implemented
1421  */
1422 ULONG
1423 NTAPI
1424 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType,
1425                       IN ULONG BusNumber,
1426                       IN ULONG BusInterruptLevel,
1427                       IN ULONG BusInterruptVector,
1428                       OUT PKIRQL Irql,
1429                       OUT PKAFFINITY Affinity)
1430 {
1431     PBUS_HANDLER Handler;
1432     ULONG Vector;
1433     PAGED_CODE();
1434 
1435     /* Defaults */
1436     *Irql = 0;
1437     *Affinity = 0;
1438 
1439     /* Find the handler */
1440     Handler = HalReferenceHandlerForBus(InterfaceType, BusNumber);
1441     if (!Handler) return 0;
1442 
1443     /* Do the assignment */
1444     Vector = Handler->GetInterruptVector(Handler,
1445                                          Handler,
1446                                          BusInterruptLevel,
1447                                          BusInterruptVector,
1448                                          Irql,
1449                                          Affinity);
1450     if ((Vector != IRQ2VECTOR(BusInterruptLevel)) ||
1451         (*Irql != VECTOR2IRQL(IRQ2VECTOR(BusInterruptLevel))))
1452     {
1453         DPRINT1("Returning IRQL %lx, Vector %lx for Level/Vector: %lx/%lx\n",
1454                 *Irql, Vector, BusInterruptLevel, BusInterruptVector);
1455         DPRINT1("Old HAL would've returned IRQL %lx and Vector %lx\n",
1456                 VECTOR2IRQL(IRQ2VECTOR(BusInterruptLevel)),
1457                 IRQ2VECTOR(BusInterruptLevel));
1458     }
1459 
1460     /* Dereference the handler and return */
1461     HalDereferenceBusHandler(Handler);
1462     return Vector;
1463 }
1464 
1465 /*
1466  * @implemented
1467  */
1468 ULONG
1469 NTAPI
1470 HalSetBusData(IN BUS_DATA_TYPE BusDataType,
1471               IN ULONG BusNumber,
1472               IN ULONG SlotNumber,
1473               IN PVOID Buffer,
1474               IN ULONG Length)
1475 {
1476     /* Call the extended function */
1477     return HalSetBusDataByOffset(BusDataType,
1478                                  BusNumber,
1479                                  SlotNumber,
1480                                  Buffer,
1481                                  0,
1482                                  Length);
1483 }
1484 
1485 /*
1486  * @implemented
1487  */
1488 ULONG
1489 NTAPI
1490 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
1491                       IN ULONG BusNumber,
1492                       IN ULONG SlotNumber,
1493                       IN PVOID Buffer,
1494                       IN ULONG Offset,
1495                       IN ULONG Length)
1496 {
1497     PBUS_HANDLER Handler;
1498     ULONG Status;
1499 
1500     /* Find the handler */
1501     Handler = HaliReferenceHandlerForConfigSpace(BusDataType, BusNumber);
1502     if (!Handler) return 0;
1503 
1504     /* Do the assignment */
1505     Status = Handler->SetBusData(Handler,
1506                                  Handler,
1507                                  SlotNumber,
1508                                  Buffer,
1509                                  Offset,
1510                                  Length);
1511 
1512     /* Dereference the handler and return */
1513     HalDereferenceBusHandler(Handler);
1514     return Status;
1515 }
1516 
1517 /*
1518  * @implemented
1519  */
1520 BOOLEAN
1521 NTAPI
1522 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
1523                        IN ULONG BusNumber,
1524                        IN PHYSICAL_ADDRESS BusAddress,
1525                        IN OUT PULONG AddressSpace,
1526                        OUT PPHYSICAL_ADDRESS TranslatedAddress)
1527 {
1528     /* Look as the bus type */
1529     if (InterfaceType == PCIBus)
1530     {
1531         /* Call the PCI registered function */
1532         return HalPciTranslateBusAddress(PCIBus,
1533                                          BusNumber,
1534                                          BusAddress,
1535                                          AddressSpace,
1536                                          TranslatedAddress);
1537     }
1538     else
1539     {
1540         /* Call the bus handler */
1541         return HaliTranslateBusAddress(InterfaceType,
1542                                        BusNumber,
1543                                        BusAddress,
1544                                        AddressSpace,
1545                                        TranslatedAddress);
1546     }
1547 }
1548 
1549 /* EOF */
1550