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