1 #pragma once 2 3 #define PCI_ADDRESS_MEMORY_SPACE 0x00000000 4 5 // 6 // Helper Macros 7 // 8 #define PASTE2(x,y) x ## y 9 #define POINTER_TO_(x) PASTE2(P,x) 10 #define READ_FROM(x) PASTE2(READ_PORT_, x) 11 #define WRITE_TO(x) PASTE2(WRITE_PORT_, x) 12 13 // 14 // Declares a PCI Register Read/Write Routine 15 // 16 #define TYPE_DEFINE(x, y) \ 17 ULONG \ 18 NTAPI \ 19 x( \ 20 IN PPCIPBUSDATA BusData, \ 21 IN y PciCfg, \ 22 IN PUCHAR Buffer, \ 23 IN ULONG Offset \ 24 ) 25 #define TYPE1_DEFINE(x) TYPE_DEFINE(x, PPCI_TYPE1_CFG_BITS); 26 #define TYPE2_DEFINE(x) TYPE_DEFINE(x, PPCI_TYPE2_ADDRESS_BITS); 27 28 // 29 // Defines a PCI Register Read/Write Type 1 Routine Prologue and Epilogue 30 // 31 #define TYPE1_START(x, y) \ 32 TYPE_DEFINE(x, PPCI_TYPE1_CFG_BITS) \ 33 { \ 34 ULONG i = Offset % sizeof(ULONG); \ 35 PciCfg->u.bits.RegisterNumber = Offset / sizeof(ULONG); \ 36 WRITE_PORT_ULONG(BusData->Config.Type1.Address, PciCfg->u.AsULONG); 37 #define TYPE1_END(y) \ 38 return sizeof(y); } 39 #define TYPE2_END TYPE1_END 40 41 // 42 // PCI Register Read Type 1 Routine 43 // 44 #define TYPE1_READ(x, y) \ 45 TYPE1_START(x, y) \ 46 *((POINTER_TO_(y))Buffer) = \ 47 READ_FROM(y)((POINTER_TO_(y))(ULONG_PTR)(BusData->Config.Type1.Data + i)); \ 48 TYPE1_END(y) 49 50 // 51 // PCI Register Write Type 1 Routine 52 // 53 #define TYPE1_WRITE(x, y) \ 54 TYPE1_START(x, y) \ 55 WRITE_TO(y)((POINTER_TO_(y))(ULONG_PTR)(BusData->Config.Type1.Data + i), \ 56 *((POINTER_TO_(y))Buffer)); \ 57 TYPE1_END(y) 58 59 // 60 // Defines a PCI Register Read/Write Type 2 Routine Prologue and Epilogue 61 // 62 #define TYPE2_START(x, y) \ 63 TYPE_DEFINE(x, PPCI_TYPE2_ADDRESS_BITS) \ 64 { \ 65 PciCfg->u.bits.RegisterNumber = (USHORT)Offset; 66 67 // 68 // PCI Register Read Type 2 Routine 69 // 70 #define TYPE2_READ(x, y) \ 71 TYPE2_START(x, y) \ 72 *((POINTER_TO_(y))Buffer) = \ 73 READ_FROM(y)((POINTER_TO_(y))(ULONG_PTR)PciCfg->u.AsUSHORT); \ 74 TYPE2_END(y) 75 76 // 77 // PCI Register Write Type 2 Routine 78 // 79 #define TYPE2_WRITE(x, y) \ 80 TYPE2_START(x, y) \ 81 WRITE_TO(y)((POINTER_TO_(y))(ULONG_PTR)PciCfg->u.AsUSHORT, \ 82 *((POINTER_TO_(y))Buffer)); \ 83 TYPE2_END(y) 84 85 typedef NTSTATUS 86 (NTAPI *PciIrqRange)( 87 IN PBUS_HANDLER BusHandler, 88 IN PBUS_HANDLER RootHandler, 89 IN PCI_SLOT_NUMBER PciSlot, 90 OUT PSUPPORTED_RANGE *Interrupt 91 ); 92 93 typedef struct _PCIPBUSDATA 94 { 95 PCIBUSDATA CommonData; 96 union 97 { 98 struct 99 { 100 PULONG Address; 101 ULONG Data; 102 } Type1; 103 struct 104 { 105 PUCHAR CSE; 106 PUCHAR Forward; 107 ULONG Base; 108 } Type2; 109 } Config; 110 ULONG MaxDevice; 111 PciIrqRange GetIrqRange; 112 BOOLEAN BridgeConfigRead; 113 UCHAR ParentBus; 114 UCHAR Subtractive; 115 UCHAR reserved[1]; 116 UCHAR SwizzleIn[4]; 117 RTL_BITMAP DeviceConfigured; 118 ULONG ConfiguredBits[PCI_MAX_DEVICES * PCI_MAX_FUNCTION / 32]; 119 } PCIPBUSDATA, *PPCIPBUSDATA; 120 121 typedef ULONG 122 (NTAPI *FncConfigIO)( 123 IN PPCIPBUSDATA BusData, 124 IN PVOID State, 125 IN PUCHAR Buffer, 126 IN ULONG Offset 127 ); 128 129 typedef VOID 130 (NTAPI *FncSync)( 131 IN PBUS_HANDLER BusHandler, 132 IN PCI_SLOT_NUMBER Slot, 133 IN PKIRQL Irql, 134 IN PVOID State 135 ); 136 137 typedef VOID 138 (NTAPI *FncReleaseSync)( 139 IN PBUS_HANDLER BusHandler, 140 IN KIRQL Irql 141 ); 142 143 typedef struct _PCI_CONFIG_HANDLER 144 { 145 FncSync Synchronize; 146 FncReleaseSync ReleaseSynchronzation; 147 FncConfigIO ConfigRead[3]; 148 FncConfigIO ConfigWrite[3]; 149 } PCI_CONFIG_HANDLER, *PPCI_CONFIG_HANDLER; 150 151 typedef struct _PCI_REGISTRY_INFO_INTERNAL 152 { 153 UCHAR MajorRevision; 154 UCHAR MinorRevision; 155 UCHAR NoBuses; // Number Of Buses 156 UCHAR HardwareMechanism; 157 ULONG ElementCount; 158 PCI_CARD_DESCRIPTOR CardList[ANYSIZE_ARRAY]; 159 } PCI_REGISTRY_INFO_INTERNAL, *PPCI_REGISTRY_INFO_INTERNAL; 160 161 // 162 // PCI Type 1 Ports 163 // 164 #define PCI_TYPE1_ADDRESS_PORT (PULONG)0xCF8 165 #define PCI_TYPE1_DATA_PORT 0xCFC 166 167 // 168 // PCI Type 2 Ports 169 // 170 #define PCI_TYPE2_CSE_PORT (PUCHAR)0xCF8 171 #define PCI_TYPE2_FORWARD_PORT (PUCHAR)0xCFA 172 #define PCI_TYPE2_ADDRESS_BASE 0xC 173 174 // 175 // PCI Type 1 Configuration Register 176 // 177 typedef struct _PCI_TYPE1_CFG_BITS 178 { 179 union 180 { 181 struct 182 { 183 ULONG Reserved1:2; 184 ULONG RegisterNumber:6; 185 ULONG FunctionNumber:3; 186 ULONG DeviceNumber:5; 187 ULONG BusNumber:8; 188 ULONG Reserved2:7; 189 ULONG Enable:1; 190 } bits; 191 192 ULONG AsULONG; 193 } u; 194 } PCI_TYPE1_CFG_BITS, *PPCI_TYPE1_CFG_BITS; 195 196 // 197 // PCI Type 2 CSE Register 198 // 199 typedef struct _PCI_TYPE2_CSE_BITS 200 { 201 union 202 { 203 struct 204 { 205 UCHAR Enable:1; 206 UCHAR FunctionNumber:3; 207 UCHAR Key:4; 208 } bits; 209 210 UCHAR AsUCHAR; 211 } u; 212 } PCI_TYPE2_CSE_BITS, PPCI_TYPE2_CSE_BITS; 213 214 // 215 // PCI Type 2 Address Register 216 // 217 typedef struct _PCI_TYPE2_ADDRESS_BITS 218 { 219 union 220 { 221 struct 222 { 223 USHORT RegisterNumber:8; 224 USHORT Agent:4; 225 USHORT AddressBase:4; 226 } bits; 227 228 USHORT AsUSHORT; 229 } u; 230 } PCI_TYPE2_ADDRESS_BITS, *PPCI_TYPE2_ADDRESS_BITS; 231 232 typedef struct _PCI_TYPE0_CFG_CYCLE_BITS 233 { 234 union 235 { 236 struct 237 { 238 ULONG Reserved1:2; 239 ULONG RegisterNumber:6; 240 ULONG FunctionNumber:3; 241 ULONG Reserved2:21; 242 } bits; 243 ULONG AsULONG; 244 } u; 245 } PCI_TYPE0_CFG_CYCLE_BITS, *PPCI_TYPE0_CFG_CYCLE_BITS; 246 247 typedef union _PCI_TYPE1_CFG_CYCLE_BITS 248 { 249 struct 250 { 251 ULONG InUse:2; 252 ULONG RegisterNumber:6; 253 ULONG FunctionNumber:3; 254 ULONG DeviceNumber:5; 255 ULONG BusNumber:8; 256 ULONG Reserved2:8; 257 }; 258 ULONG AsULONG; 259 } PCI_TYPE1_CFG_CYCLE_BITS, *PPCI_TYPE1_CFG_CYCLE_BITS; 260 261 typedef struct _ARRAY 262 { 263 ULONG ArraySize; 264 PVOID Element[ANYSIZE_ARRAY]; 265 } ARRAY, *PARRAY; 266 267 typedef struct _HAL_BUS_HANDLER 268 { 269 LIST_ENTRY AllHandlers; 270 ULONG ReferenceCount; 271 BUS_HANDLER Handler; 272 } HAL_BUS_HANDLER, *PHAL_BUS_HANDLER; 273 274 /* FUNCTIONS *****************************************************************/ 275 276 /* SHARED (Fake PCI-BUS HANDLER) */ 277 278 extern PCI_CONFIG_HANDLER PCIConfigHandler; 279 extern PCI_CONFIG_HANDLER PCIConfigHandlerType1; 280 extern PCI_CONFIG_HANDLER PCIConfigHandlerType2; 281 282 CODE_SEG("INIT") 283 PPCI_REGISTRY_INFO_INTERNAL 284 NTAPI 285 HalpQueryPciRegistryInfo( 286 VOID 287 ); 288 289 VOID 290 NTAPI 291 HalpPCISynchronizeType1( 292 IN PBUS_HANDLER BusHandler, 293 IN PCI_SLOT_NUMBER Slot, 294 IN PKIRQL Irql, 295 IN PPCI_TYPE1_CFG_BITS PciCfg 296 ); 297 298 VOID 299 NTAPI 300 HalpPCIReleaseSynchronzationType1( 301 IN PBUS_HANDLER BusHandler, 302 IN KIRQL Irql 303 ); 304 305 VOID 306 NTAPI 307 HalpPCISynchronizeType2( 308 IN PBUS_HANDLER BusHandler, 309 IN PCI_SLOT_NUMBER Slot, 310 IN PKIRQL Irql, 311 IN PPCI_TYPE2_ADDRESS_BITS PciCfg 312 ); 313 314 VOID 315 NTAPI 316 HalpPCIReleaseSynchronizationType2( 317 IN PBUS_HANDLER BusHandler, 318 IN KIRQL Irql 319 ); 320 321 TYPE1_DEFINE(HalpPCIReadUcharType1); 322 TYPE1_DEFINE(HalpPCIReadUshortType1); 323 TYPE1_DEFINE(HalpPCIReadUlongType1); 324 TYPE2_DEFINE(HalpPCIReadUcharType2); 325 TYPE2_DEFINE(HalpPCIReadUshortType2); 326 TYPE2_DEFINE(HalpPCIReadUlongType2); 327 TYPE1_DEFINE(HalpPCIWriteUcharType1); 328 TYPE1_DEFINE(HalpPCIWriteUshortType1); 329 TYPE1_DEFINE(HalpPCIWriteUlongType1); 330 TYPE2_DEFINE(HalpPCIWriteUcharType2); 331 TYPE2_DEFINE(HalpPCIWriteUshortType2); 332 TYPE2_DEFINE(HalpPCIWriteUlongType2); 333 334 BOOLEAN 335 NTAPI 336 HalpValidPCISlot( 337 IN PBUS_HANDLER BusHandler, 338 IN PCI_SLOT_NUMBER Slot 339 ); 340 341 VOID 342 NTAPI 343 HalpReadPCIConfig( 344 IN PBUS_HANDLER BusHandler, 345 IN PCI_SLOT_NUMBER Slot, 346 IN PVOID Buffer, 347 IN ULONG Offset, 348 IN ULONG Length 349 ); 350 351 VOID 352 NTAPI 353 HalpWritePCIConfig( 354 IN PBUS_HANDLER BusHandler, 355 IN PCI_SLOT_NUMBER Slot, 356 IN PVOID Buffer, 357 IN ULONG Offset, 358 IN ULONG Length 359 ); 360 361 ULONG 362 NTAPI 363 HalpGetPCIData( 364 IN PBUS_HANDLER BusHandler, 365 IN PBUS_HANDLER RootBusHandler, 366 IN ULONG SlotNumber, 367 IN PVOID Buffer, 368 IN ULONG Offset, 369 IN ULONG Length 370 ); 371 372 ULONG 373 NTAPI 374 HalpSetPCIData( 375 IN PBUS_HANDLER BusHandler, 376 IN PBUS_HANDLER RootBusHandler, 377 IN ULONG SlotNumber, 378 IN PVOID Buffer, 379 IN ULONG Offset, 380 IN ULONG Length 381 ); 382 383 NTSTATUS 384 NTAPI 385 HalpAssignPCISlotResources( 386 IN PBUS_HANDLER BusHandler, 387 IN PBUS_HANDLER RootHandler, 388 IN PUNICODE_STRING RegistryPath, 389 IN PUNICODE_STRING DriverClassName OPTIONAL, 390 IN PDRIVER_OBJECT DriverObject, 391 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 392 IN ULONG Slot, 393 IN OUT PCM_RESOURCE_LIST *pAllocatedResources 394 ); 395 396 CODE_SEG("INIT") 397 ULONG 398 HalpPhase0GetPciDataByOffset( 399 _In_ ULONG Bus, 400 _In_ PCI_SLOT_NUMBER PciSlot, 401 _Out_writes_bytes_all_(Length) PVOID Buffer, 402 _In_ ULONG Offset, 403 _In_ ULONG Length); 404 405 CODE_SEG("INIT") 406 ULONG 407 HalpPhase0SetPciDataByOffset( 408 _In_ ULONG Bus, 409 _In_ PCI_SLOT_NUMBER PciSlot, 410 _In_reads_bytes_(Length) PVOID Buffer, 411 _In_ ULONG Offset, 412 _In_ ULONG Length); 413 414 /* NON-LEGACY */ 415 416 ULONG 417 NTAPI 418 HalpGetRootInterruptVector( 419 _In_ ULONG BusInterruptLevel, 420 _In_ ULONG BusInterruptVector, 421 _Out_ PKIRQL Irql, 422 _Out_ PKAFFINITY Affinity); 423 424 ULONG 425 NTAPI 426 HalpGetCmosData( 427 _In_ ULONG BusNumber, 428 _In_ ULONG SlotNumber, 429 _Out_writes_bytes_(Length) PVOID Buffer, 430 _In_ ULONG Length 431 ); 432 433 ULONG 434 NTAPI 435 HalpSetCmosData( 436 IN ULONG BusNumber, 437 IN ULONG SlotNumber, 438 IN PVOID Buffer, 439 IN ULONG Length 440 ); 441 442 CODE_SEG("INIT") 443 VOID 444 NTAPI 445 HalpInitializePciBus( 446 VOID 447 ); 448 449 CODE_SEG("INIT") 450 VOID 451 NTAPI 452 HalpInitializePciStubs( 453 VOID 454 ); 455 456 BOOLEAN 457 NTAPI 458 HalpTranslateBusAddress( 459 IN INTERFACE_TYPE InterfaceType, 460 IN ULONG BusNumber, 461 IN PHYSICAL_ADDRESS BusAddress, 462 IN OUT PULONG AddressSpace, 463 OUT PPHYSICAL_ADDRESS TranslatedAddress 464 ); 465 466 NTSTATUS 467 NTAPI 468 HalpAssignSlotResources( 469 IN PUNICODE_STRING RegistryPath, 470 IN PUNICODE_STRING DriverClassName, 471 IN PDRIVER_OBJECT DriverObject, 472 IN PDEVICE_OBJECT DeviceObject, 473 IN INTERFACE_TYPE BusType, 474 IN ULONG BusNumber, 475 IN ULONG SlotNumber, 476 IN OUT PCM_RESOURCE_LIST *AllocatedResources 477 ); 478 479 BOOLEAN 480 NTAPI 481 HalpFindBusAddressTranslation( 482 IN PHYSICAL_ADDRESS BusAddress, 483 IN OUT PULONG AddressSpace, 484 OUT PPHYSICAL_ADDRESS TranslatedAddress, 485 IN OUT PULONG_PTR Context, 486 IN BOOLEAN NextBus 487 ); 488 489 CODE_SEG("INIT") 490 VOID 491 NTAPI 492 HalpRegisterPciDebuggingDeviceInfo( 493 VOID 494 ); 495 496 /* LEGACY */ 497 498 BOOLEAN 499 NTAPI 500 HaliTranslateBusAddress( 501 IN INTERFACE_TYPE InterfaceType, 502 IN ULONG BusNumber, 503 IN PHYSICAL_ADDRESS BusAddress, 504 IN OUT PULONG AddressSpace, 505 OUT PPHYSICAL_ADDRESS TranslatedAddress 506 ); 507 508 BOOLEAN 509 NTAPI 510 HaliFindBusAddressTranslation( 511 IN PHYSICAL_ADDRESS BusAddress, 512 IN OUT PULONG AddressSpace, 513 OUT PPHYSICAL_ADDRESS TranslatedAddress, 514 IN OUT PULONG_PTR Context, 515 IN BOOLEAN NextBus 516 ); 517 518 NTSTATUS 519 NTAPI 520 HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, 521 IN PBUS_HANDLER RootHandler, 522 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList); 523 524 ULONG 525 NTAPI 526 HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, 527 IN PBUS_HANDLER RootHandler, 528 IN ULONG BusInterruptLevel, 529 IN ULONG BusInterruptVector, 530 OUT PKIRQL Irql, 531 OUT PKAFFINITY Affinity); 532 VOID 533 NTAPI 534 HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, 535 IN PBUS_HANDLER RootHandler, 536 IN PCI_SLOT_NUMBER SlotNumber, 537 IN PPCI_COMMON_CONFIG PciData); 538 539 VOID 540 NTAPI 541 HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, 542 IN PBUS_HANDLER RootHandler, 543 IN PCI_SLOT_NUMBER SlotNumber, 544 IN PPCI_COMMON_CONFIG PciNewData, 545 IN PPCI_COMMON_CONFIG PciOldData); 546 547 NTSTATUS 548 NTAPI 549 HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, 550 IN PBUS_HANDLER RootHandler, 551 IN PCI_SLOT_NUMBER PciSlot, 552 OUT PSUPPORTED_RANGE *Range); 553 554 VOID 555 NTAPI 556 HalpInitBusHandler( 557 VOID 558 ); 559 560 PBUS_HANDLER 561 NTAPI 562 HalpContextToBusHandler( 563 IN ULONG_PTR ContextValue 564 ); 565 566 PBUS_HANDLER 567 FASTCALL 568 HaliReferenceHandlerForConfigSpace( 569 IN BUS_DATA_TYPE ConfigType, 570 IN ULONG BusNumber 571 ); 572 573 ULONG 574 NTAPI 575 HalpNoBusData( 576 IN PBUS_HANDLER BusHandler, 577 IN PBUS_HANDLER RootHandler, 578 IN ULONG SlotNumber, 579 IN PVOID Buffer, 580 IN ULONG Offset, 581 IN ULONG Length 582 ); 583 584 ULONG 585 NTAPI 586 HalpcGetCmosData( 587 IN PBUS_HANDLER BusHandler, 588 IN PBUS_HANDLER RootHandler, 589 IN ULONG SlotNumber, 590 IN PVOID Buffer, 591 IN ULONG Offset, 592 IN ULONG Length 593 ); 594 595 ULONG 596 NTAPI 597 HalpcSetCmosData( 598 IN PBUS_HANDLER BusHandler, 599 IN PBUS_HANDLER RootHandler, 600 IN ULONG SlotNumber, 601 IN PVOID Buffer, 602 IN ULONG Offset, 603 IN ULONG Length 604 ); 605 606 BOOLEAN 607 NTAPI 608 HalpTranslateSystemBusAddress( 609 IN PBUS_HANDLER BusHandler, 610 IN PBUS_HANDLER RootHandler, 611 IN PHYSICAL_ADDRESS BusAddress, 612 IN OUT PULONG AddressSpace, 613 OUT PPHYSICAL_ADDRESS TranslatedAddress 614 ); 615 616 BOOLEAN 617 NTAPI 618 HalpTranslateIsaBusAddress( 619 IN PBUS_HANDLER BusHandler, 620 IN PBUS_HANDLER RootHandler, 621 IN PHYSICAL_ADDRESS BusAddress, 622 IN OUT PULONG AddressSpace, 623 OUT PPHYSICAL_ADDRESS TranslatedAddress 624 ); 625 626 ULONG 627 NTAPI 628 HalpGetSystemInterruptVector( 629 IN PBUS_HANDLER BusHandler, 630 IN PBUS_HANDLER RootHandler, 631 IN ULONG BusInterruptLevel, 632 IN ULONG BusInterruptVector, 633 OUT PKIRQL Irql, 634 OUT PKAFFINITY Affinity 635 ); 636 637 extern ULONG HalpBusType; 638 extern BOOLEAN HalpPCIConfigInitialized; 639 extern BUS_HANDLER HalpFakePciBusHandler; 640 extern ULONG HalpMinPciBus, HalpMaxPciBus; 641 extern LIST_ENTRY HalpAllBusHandlers; 642 643 /* EOF */ 644