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