[HAL]: Detect IDE controllers. Their interrupts should not be masked.
[reactos.git] / reactos / hal / halx86 / generic / legacy / bussupp.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/legacy/bussupp.c
5 * PURPOSE: HAL Legacy Bus Support Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
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) return NULL;
43
44 /* Check for a valid interface */
45 if (InterfaceType != InterfaceTypeUndefined)
46 {
47 /* Allocate address ranges and zero them out */
48 Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPool,
49 sizeof(SUPPORTED_RANGES),
50 ' laH');
51 RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES));
52
53 /* Build the data structure */
54 Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION;
55 Bus->BusAddresses->Dma.Limit = 7;
56 Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF;
57 Bus->BusAddresses->IO.Limit = 0xFFFF;
58 Bus->BusAddresses->IO.SystemAddressSpace = 1;
59 Bus->BusAddresses->PrefetchMemory.Base = 1;
60 }
61
62 /* Return the bus address */
63 return Bus;
64 }
65
66 VOID
67 NTAPI
68 HalpRegisterInternalBusHandlers(VOID)
69 {
70 PBUS_HANDLER Bus;
71
72 /* Only do processor 1 */
73 if (KeGetCurrentPrcb()->Number) return;
74
75 /* Register root support */
76 HalpInitBusHandler();
77
78 /* Allocate the system bus */
79 Bus = HalpAllocateBusHandler(Internal,
80 ConfigurationSpaceUndefined,
81 0,
82 InterfaceTypeUndefined,
83 0,
84 0);
85 DPRINT1("Registering Internal Bus: %p\n", Bus);
86 if (Bus)
87 {
88 /* Set it up */
89 Bus->GetInterruptVector = HalpGetSystemInterruptVector;
90 Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
91 }
92
93 /* Allocate the CMOS bus */
94 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
95 Cmos,
96 0,
97 InterfaceTypeUndefined,
98 0,
99 0);
100 DPRINT1("Registering CMOS Bus: %p\n", Bus);
101 if (Bus)
102 {
103 /* Set it up */
104 Bus->GetBusData = HalpcGetCmosData;
105 Bus->SetBusData = HalpcSetCmosData;
106 }
107
108 /* Allocate the CMOS bus */
109 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
110 Cmos,
111 1,
112 InterfaceTypeUndefined,
113 0,
114 0);
115 DPRINT1("Registering CMOS Bus: %p\n", Bus);
116 if (Bus)
117 {
118 /* Set it up */
119 Bus->GetBusData = HalpcGetCmosData;
120 Bus->SetBusData = HalpcSetCmosData;
121 }
122
123 /* Allocate ISA bus */
124 Bus = HalpAllocateBusHandler(Isa,
125 ConfigurationSpaceUndefined,
126 0,
127 Internal,
128 0,
129 0);
130 DPRINT1("Registering ISA Bus: %p\n", Bus);
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 NTSTATUS
145 NTAPI
146 HalpMarkChipsetDecode(BOOLEAN OverrideEnable)
147 {
148 NTSTATUS Status;
149 UNICODE_STRING KeyString;
150 ULONG Data = OverrideEnable;
151 HANDLE KeyHandle, Handle;
152
153 /* Open CCS key */
154 RtlInitUnicodeString(&KeyString,
155 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
156 Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
157 if (NT_SUCCESS(Status))
158 {
159 /* Open PNP Bios key */
160 RtlInitUnicodeString(&KeyString, L"Control\\Biosinfo\\PNPBios");
161 Status = HalpOpenRegistryKey(&KeyHandle,
162 Handle,
163 &KeyString,
164 KEY_ALL_ACCESS,
165 TRUE);
166
167 /* Close root key */
168 ZwClose(Handle);
169
170 /* Check if PNP BIOS key exists */
171 if (NT_SUCCESS(Status))
172 {
173 /* Set the override value */
174 RtlInitUnicodeString(&KeyString, L"FullDecodeChipsetOverride");
175 Status = ZwSetValueKey(KeyHandle,
176 &KeyString,
177 0,
178 REG_DWORD,
179 &Data,
180 sizeof(Data));
181
182 /* Close subkey */
183 ZwClose(KeyHandle);
184 }
185 }
186
187 /* Return status */
188 return Status;
189 }
190
191 PBUS_HANDLER
192 NTAPI
193 HalpAllocateAndInitPciBusHandler(IN ULONG PciType,
194 IN ULONG BusNo,
195 IN BOOLEAN TestAllocation)
196 {
197 PBUS_HANDLER Bus;
198 PPCIPBUSDATA BusData;
199
200 /* Allocate the bus handler */
201 Bus = HalpAllocateBusHandler(PCIBus,
202 PCIConfiguration,
203 BusNo,
204 Internal,
205 0,
206 sizeof(PCIPBUSDATA));
207
208 /* Set it up */
209 Bus->GetBusData = (PGETSETBUSDATA)HalpGetPCIData;
210 Bus->SetBusData = (PGETSETBUSDATA)HalpSetPCIData;
211 Bus->GetInterruptVector = (PGETINTERRUPTVECTOR)HalpGetPCIIntOnISABus;
212 Bus->AdjustResourceList = (PADJUSTRESOURCELIST)HalpAdjustPCIResourceList;
213 Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES)HalpAssignPCISlotResources;
214 Bus->BusAddresses->Dma.Limit = 0;
215
216 /* Get our custom bus data */
217 BusData = (PPCIPBUSDATA)Bus->BusData;
218
219 /* Setup custom bus data */
220 BusData->CommonData.Tag = PCI_DATA_TAG;
221 BusData->CommonData.Version = PCI_DATA_VERSION;
222 BusData->CommonData.ReadConfig = (PciReadWriteConfig)HalpReadPCIConfig;
223 BusData->CommonData.WriteConfig = (PciReadWriteConfig)HalpWritePCIConfig;
224 BusData->CommonData.Pin2Line = (PciPin2Line)HalpPCIPin2ISALine;
225 BusData->CommonData.Line2Pin = (PciLine2Pin)HalpPCIISALine2Pin;
226 BusData->MaxDevice = PCI_MAX_DEVICES;
227 BusData->GetIrqRange = (PciIrqRange)HalpGetISAFixedPCIIrq;
228
229 /* Initialize the bitmap */
230 RtlInitializeBitMap(&BusData->DeviceConfigured, BusData->ConfiguredBits, 256);
231
232 /* Check the type of PCI bus */
233 switch (PciType)
234 {
235 /* Type 1 PCI Bus */
236 case 1:
237
238 /* Copy the Type 1 handler data */
239 RtlCopyMemory(&PCIConfigHandler,
240 &PCIConfigHandlerType1,
241 sizeof(PCIConfigHandler));
242
243 /* Set correct I/O Ports */
244 BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT;
245 BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT;
246 break;
247
248 /* Type 2 PCI Bus */
249 case 2:
250
251 /* Copy the Type 1 handler data */
252 RtlCopyMemory(&PCIConfigHandler,
253 &PCIConfigHandlerType2,
254 sizeof (PCIConfigHandler));
255
256 /* Set correct I/O Ports */
257 BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT;
258 BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT;
259 BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE;
260
261 /* Only 16 devices supported, not 32 */
262 BusData->MaxDevice = 16;
263 break;
264
265 default:
266
267 /* Invalid type */
268 DbgPrint("HAL: Unnkown PCI type\n");
269 }
270
271 /* Return the bus handler */
272 return Bus;
273 }
274
275 BOOLEAN
276 NTAPI
277 HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler,
278 IN PCI_SLOT_NUMBER Slot)
279 {
280 UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
281 PPCI_COMMON_CONFIG PciHeader = (PVOID)DataBuffer;
282 ULONG i;
283 ULONG_PTR Address;
284
285 /* Read the PCI header */
286 HalpReadPCIConfig(BusHandler, Slot, PciHeader, 0, PCI_COMMON_HDR_LENGTH);
287
288 /* Make sure it's a valid device */
289 if ((PciHeader->VendorID == PCI_INVALID_VENDORID) ||
290 (PCI_CONFIGURATION_TYPE(PciHeader) != PCI_DEVICE_TYPE))
291 {
292 /* Bail out */
293 return FALSE;
294 }
295
296 /* Make sure interrupt numbers make sense */
297 if (((PciHeader->u.type0.InterruptPin) &&
298 (PciHeader->u.type0.InterruptPin > 4)) ||
299 (PciHeader->u.type0.InterruptLine & 0x70))
300 {
301 /* Bail out */
302 return FALSE;
303 }
304
305 /* Now scan PCI BARs */
306 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
307 {
308 /* Check what kind of address it is */
309 Address = PciHeader->u.type0.BaseAddresses[i];
310 if (Address & PCI_ADDRESS_IO_SPACE)
311 {
312 /* Highest I/O port is 65535 */
313 if (Address > 0xFFFF) return FALSE;
314 }
315 else
316 {
317 /* MMIO should be higher than 0x80000 */
318 if ((Address > 0xF) && (Address < 0x80000)) return FALSE;
319 }
320
321 /* Is this a 64-bit address? */
322 if (!(Address & PCI_ADDRESS_IO_SPACE) &&
323 ((Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT))
324 {
325 /* Check the next-next entry, since this one 64-bits wide */
326 i++;
327 }
328 }
329
330 /* Header, interrupt and address data all make sense */
331 return TRUE;
332 }
333
334 static BOOLEAN WarningsGiven[5];
335
336 NTSTATUS
337 NTAPI
338 HalpGetChipHacks(IN USHORT VendorId,
339 IN USHORT DeviceId,
340 IN UCHAR RevisionId,
341 IN PULONG HackFlags)
342 {
343 /* Not yet implemented */
344 if (!WarningsGiven[0]++) DbgPrint("HAL: Not checking for PCI Chipset Hacks. Your hardware may malfunction!\n");
345 *HackFlags = 0;
346 return STATUS_UNSUCCESSFUL;
347 }
348
349 BOOLEAN
350 NTAPI
351 HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo,
352 IN PPCI_COMMON_CONFIG PciData,
353 IN ULONG Flags)
354 {
355 /* Not yet implemented */
356 if (!WarningsGiven[1]++) DbgPrint("HAL: Not checking for PCI Cards with Extended Addressing. Your hardware may malfunction!\n");
357 return FALSE;
358 }
359
360 BOOLEAN
361 NTAPI
362 HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData)
363 {
364 /* Simple test first */
365 if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
366 (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
367 {
368 /* The device is nice enough to admit it */
369 return TRUE;
370 }
371
372 /* Symphony 82C101 */
373 if (PciData->VendorID == 0x1C1C) return TRUE;
374
375 /* ALi MS4803 or M5219 */
376 if ((PciData->VendorID == 0x10B9) &&
377 ((PciData->DeviceID == 0x5215) || (PciData->DeviceID == 0x5219)))
378 {
379 return TRUE;
380 }
381
382 /* Appian Technology */
383 if ((PciData->VendorID == 0x1097) && (PciData->DeviceID == 0x38)) return TRUE;
384
385 /* Compaq Triflex Dual EIDE Controller */
386 if ((PciData->VendorID == 0xE11) && (PciData->DeviceID == 0xAE33)) return TRUE;
387
388 /* Micron PC Tech RZ1000 */
389 if ((PciData->VendorID == 0x1042) && (PciData->DeviceID == 0x1000)) return TRUE;
390
391 /* SiS 85C601 or 5513 [IDE] */
392 if ((PciData->VendorID == 0x1039) &&
393 ((PciData->DeviceID == 0x601) || (PciData->DeviceID == 0x5513)))
394 {
395 return TRUE;
396 }
397
398 /* Symphony Labs W83769F */
399 if ((PciData->VendorID == 0x10AD) &&
400 ((PciData->DeviceID == 0x1) || (PciData->DeviceID == 0x150)))
401 {
402 return TRUE;
403 }
404
405 /* UMC UM8673F */
406 if ((PciData->VendorID == 0x1060) && (PciData->DeviceID == 0x101)) return TRUE;
407
408 /* You've survived */
409 return FALSE;
410 }
411
412 BOOLEAN
413 NTAPI
414 HalpGetPciBridgeConfig(IN ULONG PciType,
415 IN PUCHAR MaxPciBus)
416 {
417 /* Not yet implemented */
418 if (!WarningsGiven[3]++) DbgPrint("HAL: Not checking for PCI-to-PCI Bridges. Your hardware may malfunction!\n");
419 return FALSE;
420 }
421
422 VOID
423 NTAPI
424 HalpFixupPciSupportedRanges(IN ULONG MaxBuses)
425 {
426 /* Not yet implemented */
427 if (!WarningsGiven[4]++) DbgPrint("HAL: Not adjusting Bridge-to-Child PCI Address Ranges. Your hardware may malfunction!\n");
428 }
429 #endif
430
431 VOID
432 NTAPI
433 HalpInitializePciBus(VOID)
434 {
435 #ifndef _MINIHAL_
436 PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
437 UCHAR PciType;
438 PCI_SLOT_NUMBER PciSlot;
439 ULONG i, j, k;
440 UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH];
441 PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer;
442 PBUS_HANDLER BusHandler;
443 ULONG HackFlags;
444 BOOLEAN ExtendedAddressDecoding = FALSE;
445
446 /* Query registry information */
447 PciRegistryInfo = HalpQueryPciRegistryInfo();
448 if (!PciRegistryInfo) return;
449
450 /* Initialize the PCI configuration lock */
451 KeInitializeSpinLock(&HalpPCIConfigLock);
452
453 /* Get the type and free the info structure */
454 PciType = PciRegistryInfo->HardwareMechanism & 0xF;
455
456 /* Check if this is a type 2 PCI bus with at least one bus */
457 if ((PciRegistryInfo->NoBuses) && (PciType == 2))
458 {
459 /* Setup the PCI slot */
460 PciSlot.u.bits.Reserved = 0;
461 PciSlot.u.bits.FunctionNumber = 0;
462
463 /* Loop all slots */
464 for (i = 0; i < 32; i++)
465 {
466 /* Try to setup a Type 2 PCI slot */
467 PciType = 2;
468 BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE);
469 if (!BusHandler) break;
470
471 /* Now check if it's valid */
472 if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;
473
474 /* Heh, the BIOS lied... try Type 1 */
475 PciType = 1;
476 BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE);
477 if (!BusHandler) break;
478
479 /* Now check if it's valid */
480 if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break;
481
482 /* Keep trying */
483 PciType = 2;
484 }
485
486 /* Now allocate the correct kind of handler */
487 HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE);
488 }
489
490 /* Okay, now loop all PCI bridges */
491 do
492 {
493 /* Loop all PCI buses */
494 for (i = 0; i < PciRegistryInfo->NoBuses; i++)
495 {
496 /* Check if we have a handler for it */
497 if (!HalHandlerForBus(PCIBus, i))
498 {
499 /* Allocate it */
500 HalpAllocateAndInitPciBusHandler(PciType, i, FALSE);
501 }
502 }
503 /* Go to the next bridge */
504 } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses));
505
506 /* Now build correct address range informaiton */
507 HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses);
508
509 /* Loop every bus */
510 PciSlot.u.bits.Reserved = 0;
511 for (i = 0; i < PciRegistryInfo->NoBuses; i++)
512 {
513 /* Get the bus handler */
514 BusHandler = HalHandlerForBus(PCIBus, i);
515
516 /* Loop every device */
517 for (j = 0; j < 32; j++)
518 {
519 /* Loop every function */
520 PciSlot.u.bits.DeviceNumber = j;
521 for (k = 0; k < 8; k++)
522 {
523 /* Build the final slot structure */
524 PciSlot.u.bits.FunctionNumber = k;
525
526 /* Read the configuration information */
527 HalpReadPCIConfig(BusHandler,
528 PciSlot,
529 PciData,
530 0,
531 PCI_COMMON_HDR_LENGTH);
532
533 /* Skip if this is an invalid function */
534 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
535
536 /* Check if this is a Cardbus bridge */
537 if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE)
538 {
539 /* Not supported */
540 DbgPrint("HAL: Your machine has a PCI Cardbus Bridge. This is not supported!\n");
541 continue;
542 }
543
544 /* Check if this is a PCI device */
545 if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE)
546 {
547 /* Check if it has an interrupt pin and line registered */
548 if ((PciData->u.type1.InterruptPin) &&
549 (PciData->u.type1.InterruptLine))
550 {
551 /* Check if this interrupt line is connected to the bus */
552 if (PciData->u.type1.InterruptLine < 16)
553 {
554 /* Is this an IDE device? */
555 DbgPrint("HAL: Found PCI device with IRQ line\n");
556 if (!HalpIsIdeDevice(PciData))
557 {
558 /* We'll mask out this interrupt then */
559 DbgPrint("HAL: Device is not an IDE Device. Should be masking IRQ %d! This is not supported!\n",
560 PciData->u.type1.InterruptLine);
561 HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine);
562 }
563 }
564 }
565 }
566
567 /* Check for broken Intel chips */
568 if (PciData->VendorID == 0x8086)
569 {
570 /* Check for broken 82830 PCI controller */
571 if ((PciData->DeviceID == 0x04A3) &&
572 (PciData->RevisionID < 0x11))
573 {
574 /* Skip */
575 DbgPrint("HAL: Your machine has a broken Intel 82430 PCI Controller. This is not supported!\n");
576 continue;
577 }
578
579 /* Check for broken 82378 PCI-to-ISA Bridge */
580 if ((PciData->DeviceID == 0x0484) &&
581 (PciData->RevisionID <= 3))
582 {
583 /* Skip */
584 DbgPrint("HAL: Your machine has a broken Intel 82378 PCI-to-ISA Bridge. This is not supported!\n");
585 continue;
586 }
587
588 /* Check for broken 82450 PCI Bridge */
589 if ((PciData->DeviceID == 0x84C4) &&
590 (PciData->RevisionID <= 4))
591 {
592 DbgPrint("HAL: Your machine has an Intel Orion 82450 PCI Bridge. This is not supported!\n");
593 continue;
594 }
595 }
596
597 /* Do we know this card? */
598 if (!ExtendedAddressDecoding)
599 {
600 /* Check for it */
601 if (HalpIsRecognizedCard(PciRegistryInfo, PciData, 1))
602 {
603 /* We'll do chipset checks later */
604 DbgPrint("HAL: Recognized a PCI Card with Extended Address Decoding. This is not supported!\n");
605 ExtendedAddressDecoding = TRUE;
606 }
607 }
608
609 /* Check if this is a USB controller */
610 if ((PciData->BaseClass == PCI_CLASS_SERIAL_BUS_CTLR) &&
611 (PciData->SubClass == PCI_SUBCLASS_SB_USB))
612 {
613 /* Check if this is an OHCI controller */
614 if (PciData->ProgIf == 0x10)
615 {
616 DbgPrint("HAL: Your machine has an OHCI (USB) PCI Expansion Card. This is not supported!\n");
617 continue;
618 }
619
620 /* Check for Intel UHCI controller */
621 if (PciData->VendorID == 0x8086)
622 {
623 DbgPrint("HAL: Your machine has an Intel UHCI (USB) Controller. This is not supported!\n");
624 continue;
625 }
626
627 /* Check for VIA UHCI controller */
628 if (PciData->VendorID == 0x1106)
629 {
630 DbgPrint("HAL: Your machine has a VIA UHCI (USB) Controller. This is not supported!\n");
631 continue;
632 }
633 }
634
635 /* Now check the registry for chipset hacks */
636 if (NT_SUCCESS(HalpGetChipHacks(PciData->VendorID,
637 PciData->DeviceID,
638 PciData->RevisionID,
639 &HackFlags)))
640 {
641 /* Check for hibernate-disable */
642 if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE)
643 {
644 DbgPrint("HAL: Your machine has a broken PCI device which is incompatible with hibernation. This is not supported!\n");
645 continue;
646 }
647
648 /* Check for USB controllers that generate SMIs */
649 if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE)
650 {
651 DbgPrint("HAL: Your machine has a USB controller which generates SMIs. This is not supported!\n");
652 continue;
653 }
654 }
655 }
656 }
657 }
658
659 /* Initialize NMI Crash Flag */
660 HalpGetNMICrashFlag();
661
662 /* Free the registry data */
663 ExFreePool(PciRegistryInfo);
664
665 /* Tell PnP if this hard supports correct decoding */
666 HalpMarkChipsetDecode(ExtendedAddressDecoding);
667 DPRINT1("PCI BUS Setup complete\n");
668 #endif
669 }
670
671 VOID
672 NTAPI
673 HalpInitBusHandlers(VOID)
674 {
675 /* Register the HAL Bus Handler support */
676 HalpRegisterInternalBusHandlers();
677 }
678
679 VOID
680 NTAPI
681 HalpRegisterKdSupportFunctions(VOID)
682 {
683 /* Register PCI Device Functions */
684 KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging;
685 KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging;
686
687 /* Register memory functions */
688 #ifndef _MINIHAL_
689 KdMapPhysicalMemory64 = HalpMapPhysicalMemory64;
690 KdUnmapVirtualAddress = HalpUnmapVirtualAddress;
691 #endif
692
693 /* Register ACPI stub */
694 KdCheckPowerButton = HalpCheckPowerButton;
695 }
696
697 NTSTATUS
698 NTAPI
699 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath,
700 IN PUNICODE_STRING DriverClassName,
701 IN PDRIVER_OBJECT DriverObject,
702 IN PDEVICE_OBJECT DeviceObject,
703 IN INTERFACE_TYPE BusType,
704 IN ULONG BusNumber,
705 IN ULONG SlotNumber,
706 IN OUT PCM_RESOURCE_LIST *AllocatedResources)
707 {
708 BUS_HANDLER BusHandler;
709 PAGED_CODE();
710
711 /* Only PCI is supported */
712 if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED;
713
714 /* Setup fake PCI Bus handler */
715 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
716 BusHandler.BusNumber = BusNumber;
717
718 /* Call the PCI function */
719 return HalpAssignPCISlotResources(&BusHandler,
720 &BusHandler,
721 RegistryPath,
722 DriverClassName,
723 DriverObject,
724 DeviceObject,
725 SlotNumber,
726 AllocatedResources);
727 }
728
729 BOOLEAN
730 NTAPI
731 HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
732 IN ULONG BusNumber,
733 IN PHYSICAL_ADDRESS BusAddress,
734 IN OUT PULONG AddressSpace,
735 OUT PPHYSICAL_ADDRESS TranslatedAddress)
736 {
737 /* Translation is easy */
738 TranslatedAddress->QuadPart = BusAddress.QuadPart;
739 return TRUE;
740 }
741
742 ULONG
743 NTAPI
744 HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber,
745 IN ULONG BusInterruptLevel,
746 IN ULONG BusInterruptVector,
747 OUT PKIRQL Irql,
748 OUT PKAFFINITY Affinity)
749 {
750 ULONG Vector = IRQ2VECTOR(BusInterruptLevel);
751 *Irql = (KIRQL)VECTOR2IRQL(Vector);
752 *Affinity = 0xFFFFFFFF;
753 return Vector;
754 }
755
756 BOOLEAN
757 NTAPI
758 HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
759 IN OUT PULONG AddressSpace,
760 OUT PPHYSICAL_ADDRESS TranslatedAddress,
761 IN OUT PULONG_PTR Context,
762 IN BOOLEAN NextBus)
763 {
764 /* Make sure we have a context */
765 if (!Context) return FALSE;
766
767 /* If we have data in the context, then this shouldn't be a new lookup */
768 if ((*Context) && (NextBus == TRUE)) return FALSE;
769
770 /* Return bus data */
771 TranslatedAddress->QuadPart = BusAddress.QuadPart;
772
773 /* Set context value and return success */
774 *Context = 1;
775 return TRUE;
776 }
777
778 /* PUBLIC FUNCTIONS **********************************************************/
779
780 /*
781 * @implemented
782 */
783 NTSTATUS
784 NTAPI
785 HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources)
786 {
787 /* Deprecated, return success */
788 return STATUS_SUCCESS;
789 }
790
791 /*
792 * @implemented
793 */
794 NTSTATUS
795 NTAPI
796 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath,
797 IN PUNICODE_STRING DriverClassName,
798 IN PDRIVER_OBJECT DriverObject,
799 IN PDEVICE_OBJECT DeviceObject,
800 IN INTERFACE_TYPE BusType,
801 IN ULONG BusNumber,
802 IN ULONG SlotNumber,
803 IN OUT PCM_RESOURCE_LIST *AllocatedResources)
804 {
805 /* Check the bus type */
806 if (BusType != PCIBus)
807 {
808 /* Call our internal handler */
809 return HalpAssignSlotResources(RegistryPath,
810 DriverClassName,
811 DriverObject,
812 DeviceObject,
813 BusType,
814 BusNumber,
815 SlotNumber,
816 AllocatedResources);
817 }
818 else
819 {
820 /* Call the PCI registered function */
821 return HalPciAssignSlotResources(RegistryPath,
822 DriverClassName,
823 DriverObject,
824 DeviceObject,
825 PCIBus,
826 BusNumber,
827 SlotNumber,
828 AllocatedResources);
829 }
830 }
831
832 /*
833 * @implemented
834 */
835 ULONG
836 NTAPI
837 HalGetBusData(IN BUS_DATA_TYPE BusDataType,
838 IN ULONG BusNumber,
839 IN ULONG SlotNumber,
840 IN PVOID Buffer,
841 IN ULONG Length)
842 {
843 /* Call the extended function */
844 return HalGetBusDataByOffset(BusDataType,
845 BusNumber,
846 SlotNumber,
847 Buffer,
848 0,
849 Length);
850 }
851
852 /*
853 * @implemented
854 */
855 ULONG
856 NTAPI
857 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
858 IN ULONG BusNumber,
859 IN ULONG SlotNumber,
860 IN PVOID Buffer,
861 IN ULONG Offset,
862 IN ULONG Length)
863 {
864 BUS_HANDLER BusHandler;
865
866 /* Look as the bus type */
867 if (BusDataType == Cmos)
868 {
869 /* Call CMOS Function */
870 return HalpGetCmosData(0, SlotNumber, Buffer, Length);
871 }
872 else if (BusDataType == EisaConfiguration)
873 {
874 /* FIXME: TODO */
875 ASSERT(FALSE);
876 }
877 else if ((BusDataType == PCIConfiguration) &&
878 (HalpPCIConfigInitialized) &&
879 ((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus)))
880 {
881 /* Setup fake PCI Bus handler */
882 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
883 BusHandler.BusNumber = BusNumber;
884
885 /* Call PCI function */
886 return HalpGetPCIData(&BusHandler,
887 &BusHandler,
888 *(PPCI_SLOT_NUMBER)&SlotNumber,
889 Buffer,
890 Offset,
891 Length);
892 }
893
894 /* Invalid bus */
895 return 0;
896 }
897
898 /*
899 * @implemented
900 */
901 ULONG
902 NTAPI
903 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType,
904 IN ULONG BusNumber,
905 IN ULONG BusInterruptLevel,
906 IN ULONG BusInterruptVector,
907 OUT PKIRQL Irql,
908 OUT PKAFFINITY Affinity)
909 {
910 /* Call the system bus translator */
911 return HalpGetSystemInterruptVector_Acpi(BusNumber,
912 BusInterruptLevel,
913 BusInterruptVector,
914 Irql,
915 Affinity);
916 }
917
918 /*
919 * @implemented
920 */
921 ULONG
922 NTAPI
923 HalSetBusData(IN BUS_DATA_TYPE BusDataType,
924 IN ULONG BusNumber,
925 IN ULONG SlotNumber,
926 IN PVOID Buffer,
927 IN ULONG Length)
928 {
929 /* Call the extended function */
930 return HalSetBusDataByOffset(BusDataType,
931 BusNumber,
932 SlotNumber,
933 Buffer,
934 0,
935 Length);
936 }
937
938 /*
939 * @implemented
940 */
941 ULONG
942 NTAPI
943 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
944 IN ULONG BusNumber,
945 IN ULONG SlotNumber,
946 IN PVOID Buffer,
947 IN ULONG Offset,
948 IN ULONG Length)
949 {
950 BUS_HANDLER BusHandler;
951
952 /* Look as the bus type */
953 if (BusDataType == Cmos)
954 {
955 /* Call CMOS Function */
956 return HalpSetCmosData(0, SlotNumber, Buffer, Length);
957 }
958 else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized))
959 {
960 /* Setup fake PCI Bus handler */
961 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
962 BusHandler.BusNumber = BusNumber;
963
964 /* Call PCI function */
965 return HalpSetPCIData(&BusHandler,
966 &BusHandler,
967 *(PPCI_SLOT_NUMBER)&SlotNumber,
968 Buffer,
969 Offset,
970 Length);
971 }
972
973 /* Invalid bus */
974 return 0;
975 }
976
977 /*
978 * @implemented
979 */
980 BOOLEAN
981 NTAPI
982 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
983 IN ULONG BusNumber,
984 IN PHYSICAL_ADDRESS BusAddress,
985 IN OUT PULONG AddressSpace,
986 OUT PPHYSICAL_ADDRESS TranslatedAddress)
987 {
988 /* Look as the bus type */
989 if (InterfaceType == PCIBus)
990 {
991 /* Call the PCI registered function */
992 return HalPciTranslateBusAddress(PCIBus,
993 BusNumber,
994 BusAddress,
995 AddressSpace,
996 TranslatedAddress);
997 }
998 else
999 {
1000 /* Translation is easy */
1001 TranslatedAddress->QuadPart = BusAddress.QuadPart;
1002 return TRUE;
1003 }
1004 }
1005
1006 /* EOF */