[REACTOS] Cleanup INIT and some PAGE section allocations
[reactos.git] / hal / halx86 / legacy / bussupp.c
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 */