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 ULONG 433 NTAPI 434 HalpSetCmosData( 435 _In_ ULONG BusNumber, 436 _In_ ULONG SlotNumber, 437 _In_reads_bytes_(Length) PVOID Buffer, 438 _In_ ULONG Length); 439 440 CODE_SEG("INIT") 441 VOID 442 NTAPI 443 HalpInitializePciBus( 444 VOID 445 ); 446 447 CODE_SEG("INIT") 448 VOID 449 NTAPI 450 HalpInitializePciStubs( 451 VOID 452 ); 453 454 BOOLEAN 455 NTAPI 456 HalpTranslateBusAddress( 457 IN INTERFACE_TYPE InterfaceType, 458 IN ULONG BusNumber, 459 IN PHYSICAL_ADDRESS BusAddress, 460 IN OUT PULONG AddressSpace, 461 OUT PPHYSICAL_ADDRESS TranslatedAddress 462 ); 463 464 NTSTATUS 465 NTAPI 466 HalpAssignSlotResources( 467 IN PUNICODE_STRING RegistryPath, 468 IN PUNICODE_STRING DriverClassName, 469 IN PDRIVER_OBJECT DriverObject, 470 IN PDEVICE_OBJECT DeviceObject, 471 IN INTERFACE_TYPE BusType, 472 IN ULONG BusNumber, 473 IN ULONG SlotNumber, 474 IN OUT PCM_RESOURCE_LIST *AllocatedResources 475 ); 476 477 BOOLEAN 478 NTAPI 479 HalpFindBusAddressTranslation( 480 IN PHYSICAL_ADDRESS BusAddress, 481 IN OUT PULONG AddressSpace, 482 OUT PPHYSICAL_ADDRESS TranslatedAddress, 483 IN OUT PULONG_PTR Context, 484 IN BOOLEAN NextBus 485 ); 486 487 CODE_SEG("INIT") 488 VOID 489 NTAPI 490 HalpRegisterPciDebuggingDeviceInfo( 491 VOID 492 ); 493 494 /* LEGACY */ 495 496 BOOLEAN 497 NTAPI 498 HaliTranslateBusAddress( 499 IN INTERFACE_TYPE InterfaceType, 500 IN ULONG BusNumber, 501 IN PHYSICAL_ADDRESS BusAddress, 502 IN OUT PULONG AddressSpace, 503 OUT PPHYSICAL_ADDRESS TranslatedAddress 504 ); 505 506 BOOLEAN 507 NTAPI 508 HaliFindBusAddressTranslation( 509 IN PHYSICAL_ADDRESS BusAddress, 510 IN OUT PULONG AddressSpace, 511 OUT PPHYSICAL_ADDRESS TranslatedAddress, 512 IN OUT PULONG_PTR Context, 513 IN BOOLEAN NextBus 514 ); 515 516 NTSTATUS 517 NTAPI 518 HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, 519 IN PBUS_HANDLER RootHandler, 520 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList); 521 522 ULONG 523 NTAPI 524 HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, 525 IN PBUS_HANDLER RootHandler, 526 IN ULONG BusInterruptLevel, 527 IN ULONG BusInterruptVector, 528 OUT PKIRQL Irql, 529 OUT PKAFFINITY Affinity); 530 VOID 531 NTAPI 532 HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, 533 IN PBUS_HANDLER RootHandler, 534 IN PCI_SLOT_NUMBER SlotNumber, 535 IN PPCI_COMMON_CONFIG PciData); 536 537 VOID 538 NTAPI 539 HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, 540 IN PBUS_HANDLER RootHandler, 541 IN PCI_SLOT_NUMBER SlotNumber, 542 IN PPCI_COMMON_CONFIG PciNewData, 543 IN PPCI_COMMON_CONFIG PciOldData); 544 545 NTSTATUS 546 NTAPI 547 HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, 548 IN PBUS_HANDLER RootHandler, 549 IN PCI_SLOT_NUMBER PciSlot, 550 OUT PSUPPORTED_RANGE *Range); 551 552 VOID 553 NTAPI 554 HalpInitBusHandler( 555 VOID 556 ); 557 558 PBUS_HANDLER 559 NTAPI 560 HalpContextToBusHandler( 561 IN ULONG_PTR ContextValue 562 ); 563 564 PBUS_HANDLER 565 FASTCALL 566 HaliReferenceHandlerForConfigSpace( 567 IN BUS_DATA_TYPE ConfigType, 568 IN ULONG BusNumber 569 ); 570 571 ULONG 572 NTAPI 573 HalpNoBusData( 574 _In_ PBUS_HANDLER BusHandler, 575 _In_ PBUS_HANDLER RootHandler, 576 _In_ ULONG SlotNumber, 577 _In_ PVOID Buffer, 578 _In_ ULONG Offset, 579 _In_ ULONG Length); 580 581 ULONG 582 NTAPI 583 HalpcGetCmosData( 584 _In_ PBUS_HANDLER BusHandler, 585 _In_ PBUS_HANDLER RootHandler, 586 _In_ ULONG SlotNumber, 587 _Out_writes_bytes_(Length) PVOID Buffer, 588 _In_ ULONG Offset, 589 _In_ ULONG Length); 590 591 ULONG 592 NTAPI 593 HalpcSetCmosData( 594 _In_ PBUS_HANDLER BusHandler, 595 _In_ PBUS_HANDLER RootHandler, 596 _In_ ULONG SlotNumber, 597 _In_reads_bytes_(Length) PVOID Buffer, 598 _In_ ULONG Offset, 599 _In_ ULONG Length); 600 601 BOOLEAN 602 NTAPI 603 HalpTranslateSystemBusAddress( 604 IN PBUS_HANDLER BusHandler, 605 IN PBUS_HANDLER RootHandler, 606 IN PHYSICAL_ADDRESS BusAddress, 607 IN OUT PULONG AddressSpace, 608 OUT PPHYSICAL_ADDRESS TranslatedAddress 609 ); 610 611 BOOLEAN 612 NTAPI 613 HalpTranslateIsaBusAddress( 614 IN PBUS_HANDLER BusHandler, 615 IN PBUS_HANDLER RootHandler, 616 IN PHYSICAL_ADDRESS BusAddress, 617 IN OUT PULONG AddressSpace, 618 OUT PPHYSICAL_ADDRESS TranslatedAddress 619 ); 620 621 ULONG 622 NTAPI 623 HalpGetSystemInterruptVector( 624 IN PBUS_HANDLER BusHandler, 625 IN PBUS_HANDLER RootHandler, 626 IN ULONG BusInterruptLevel, 627 IN ULONG BusInterruptVector, 628 OUT PKIRQL Irql, 629 OUT PKAFFINITY Affinity 630 ); 631 632 extern ULONG HalpBusType; 633 extern BOOLEAN HalpPCIConfigInitialized; 634 extern BUS_HANDLER HalpFakePciBusHandler; 635 extern ULONG HalpMinPciBus, HalpMaxPciBus; 636 extern LIST_ENTRY HalpAllBusHandlers; 637 638 /* EOF */ 639