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 struct _PCI_TYPE1_CFG_CYCLE_BITS 248 { 249 union 250 { 251 struct 252 { 253 ULONG Reserved1:2; 254 ULONG RegisterNumber:6; 255 ULONG FunctionNumber:3; 256 ULONG DeviceNumber:5; 257 ULONG BusNumber:8; 258 ULONG Reserved2:8; 259 } bits; 260 ULONG AsULONG; 261 } u; 262 } PCI_TYPE1_CFG_CYCLE_BITS, *PPCI_TYPE1_CFG_CYCLE_BITS; 263 264 typedef struct _ARRAY 265 { 266 ULONG ArraySize; 267 PVOID Element[ANYSIZE_ARRAY]; 268 } ARRAY, *PARRAY; 269 270 typedef struct _HAL_BUS_HANDLER 271 { 272 LIST_ENTRY AllHandlers; 273 ULONG ReferenceCount; 274 BUS_HANDLER Handler; 275 } HAL_BUS_HANDLER, *PHAL_BUS_HANDLER; 276 277 /* FUNCTIONS *****************************************************************/ 278 279 /* SHARED (Fake PCI-BUS HANDLER) */ 280 281 extern PCI_CONFIG_HANDLER PCIConfigHandler; 282 extern PCI_CONFIG_HANDLER PCIConfigHandlerType1; 283 extern PCI_CONFIG_HANDLER PCIConfigHandlerType2; 284 285 INIT_FUNCTION 286 PPCI_REGISTRY_INFO_INTERNAL 287 NTAPI 288 HalpQueryPciRegistryInfo( 289 VOID 290 ); 291 292 VOID 293 NTAPI 294 HalpPCISynchronizeType1( 295 IN PBUS_HANDLER BusHandler, 296 IN PCI_SLOT_NUMBER Slot, 297 IN PKIRQL Irql, 298 IN PPCI_TYPE1_CFG_BITS PciCfg 299 ); 300 301 VOID 302 NTAPI 303 HalpPCIReleaseSynchronzationType1( 304 IN PBUS_HANDLER BusHandler, 305 IN KIRQL Irql 306 ); 307 308 VOID 309 NTAPI 310 HalpPCISynchronizeType2( 311 IN PBUS_HANDLER BusHandler, 312 IN PCI_SLOT_NUMBER Slot, 313 IN PKIRQL Irql, 314 IN PPCI_TYPE2_ADDRESS_BITS PciCfg 315 ); 316 317 VOID 318 NTAPI 319 HalpPCIReleaseSynchronizationType2( 320 IN PBUS_HANDLER BusHandler, 321 IN KIRQL Irql 322 ); 323 324 TYPE1_DEFINE(HalpPCIReadUcharType1); 325 TYPE1_DEFINE(HalpPCIReadUshortType1); 326 TYPE1_DEFINE(HalpPCIReadUlongType1); 327 TYPE2_DEFINE(HalpPCIReadUcharType2); 328 TYPE2_DEFINE(HalpPCIReadUshortType2); 329 TYPE2_DEFINE(HalpPCIReadUlongType2); 330 TYPE1_DEFINE(HalpPCIWriteUcharType1); 331 TYPE1_DEFINE(HalpPCIWriteUshortType1); 332 TYPE1_DEFINE(HalpPCIWriteUlongType1); 333 TYPE2_DEFINE(HalpPCIWriteUcharType2); 334 TYPE2_DEFINE(HalpPCIWriteUshortType2); 335 TYPE2_DEFINE(HalpPCIWriteUlongType2); 336 337 BOOLEAN 338 NTAPI 339 HalpValidPCISlot( 340 IN PBUS_HANDLER BusHandler, 341 IN PCI_SLOT_NUMBER Slot 342 ); 343 344 VOID 345 NTAPI 346 HalpReadPCIConfig( 347 IN PBUS_HANDLER BusHandler, 348 IN PCI_SLOT_NUMBER Slot, 349 IN PVOID Buffer, 350 IN ULONG Offset, 351 IN ULONG Length 352 ); 353 354 VOID 355 NTAPI 356 HalpWritePCIConfig( 357 IN PBUS_HANDLER BusHandler, 358 IN PCI_SLOT_NUMBER Slot, 359 IN PVOID Buffer, 360 IN ULONG Offset, 361 IN ULONG Length 362 ); 363 364 ULONG 365 NTAPI 366 HalpGetPCIData( 367 IN PBUS_HANDLER BusHandler, 368 IN PBUS_HANDLER RootBusHandler, 369 IN ULONG SlotNumber, 370 IN PVOID Buffer, 371 IN ULONG Offset, 372 IN ULONG Length 373 ); 374 375 ULONG 376 NTAPI 377 HalpSetPCIData( 378 IN PBUS_HANDLER BusHandler, 379 IN PBUS_HANDLER RootBusHandler, 380 IN ULONG SlotNumber, 381 IN PVOID Buffer, 382 IN ULONG Offset, 383 IN ULONG Length 384 ); 385 386 NTSTATUS 387 NTAPI 388 HalpAssignPCISlotResources( 389 IN PBUS_HANDLER BusHandler, 390 IN PBUS_HANDLER RootHandler, 391 IN PUNICODE_STRING RegistryPath, 392 IN PUNICODE_STRING DriverClassName OPTIONAL, 393 IN PDRIVER_OBJECT DriverObject, 394 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 395 IN ULONG Slot, 396 IN OUT PCM_RESOURCE_LIST *pAllocatedResources 397 ); 398 399 /* NON-LEGACY */ 400 401 ULONG 402 NTAPI 403 HalpGetSystemInterruptVector_Acpi( 404 ULONG BusNumber, 405 ULONG BusInterruptLevel, 406 ULONG BusInterruptVector, 407 PKIRQL Irql, 408 PKAFFINITY Affinity 409 ); 410 411 ULONG 412 NTAPI 413 HalpGetCmosData( 414 _In_ ULONG BusNumber, 415 _In_ ULONG SlotNumber, 416 _Out_writes_bytes_(Length) PVOID Buffer, 417 _In_ ULONG Length 418 ); 419 420 ULONG 421 NTAPI 422 HalpSetCmosData( 423 IN ULONG BusNumber, 424 IN ULONG SlotNumber, 425 IN PVOID Buffer, 426 IN ULONG Length 427 ); 428 429 INIT_FUNCTION 430 VOID 431 NTAPI 432 HalpInitializePciBus( 433 VOID 434 ); 435 436 INIT_FUNCTION 437 VOID 438 NTAPI 439 HalpInitializePciStubs( 440 VOID 441 ); 442 443 BOOLEAN 444 NTAPI 445 HalpTranslateBusAddress( 446 IN INTERFACE_TYPE InterfaceType, 447 IN ULONG BusNumber, 448 IN PHYSICAL_ADDRESS BusAddress, 449 IN OUT PULONG AddressSpace, 450 OUT PPHYSICAL_ADDRESS TranslatedAddress 451 ); 452 453 NTSTATUS 454 NTAPI 455 HalpAssignSlotResources( 456 IN PUNICODE_STRING RegistryPath, 457 IN PUNICODE_STRING DriverClassName, 458 IN PDRIVER_OBJECT DriverObject, 459 IN PDEVICE_OBJECT DeviceObject, 460 IN INTERFACE_TYPE BusType, 461 IN ULONG BusNumber, 462 IN ULONG SlotNumber, 463 IN OUT PCM_RESOURCE_LIST *AllocatedResources 464 ); 465 466 BOOLEAN 467 NTAPI 468 HalpFindBusAddressTranslation( 469 IN PHYSICAL_ADDRESS BusAddress, 470 IN OUT PULONG AddressSpace, 471 OUT PPHYSICAL_ADDRESS TranslatedAddress, 472 IN OUT PULONG_PTR Context, 473 IN BOOLEAN NextBus 474 ); 475 476 INIT_FUNCTION 477 VOID 478 NTAPI 479 HalpRegisterPciDebuggingDeviceInfo( 480 VOID 481 ); 482 483 /* LEGACY */ 484 485 BOOLEAN 486 NTAPI 487 HaliTranslateBusAddress( 488 IN INTERFACE_TYPE InterfaceType, 489 IN ULONG BusNumber, 490 IN PHYSICAL_ADDRESS BusAddress, 491 IN OUT PULONG AddressSpace, 492 OUT PPHYSICAL_ADDRESS TranslatedAddress 493 ); 494 495 BOOLEAN 496 NTAPI 497 HaliFindBusAddressTranslation( 498 IN PHYSICAL_ADDRESS BusAddress, 499 IN OUT PULONG AddressSpace, 500 OUT PPHYSICAL_ADDRESS TranslatedAddress, 501 IN OUT PULONG_PTR Context, 502 IN BOOLEAN NextBus 503 ); 504 505 NTSTATUS 506 NTAPI 507 HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, 508 IN PBUS_HANDLER RootHandler, 509 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList); 510 511 ULONG 512 NTAPI 513 HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, 514 IN PBUS_HANDLER RootHandler, 515 IN ULONG BusInterruptLevel, 516 IN ULONG BusInterruptVector, 517 OUT PKIRQL Irql, 518 OUT PKAFFINITY Affinity); 519 VOID 520 NTAPI 521 HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, 522 IN PBUS_HANDLER RootHandler, 523 IN PCI_SLOT_NUMBER SlotNumber, 524 IN PPCI_COMMON_CONFIG PciData); 525 526 VOID 527 NTAPI 528 HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, 529 IN PBUS_HANDLER RootHandler, 530 IN PCI_SLOT_NUMBER SlotNumber, 531 IN PPCI_COMMON_CONFIG PciNewData, 532 IN PPCI_COMMON_CONFIG PciOldData); 533 534 NTSTATUS 535 NTAPI 536 HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, 537 IN PBUS_HANDLER RootHandler, 538 IN PCI_SLOT_NUMBER PciSlot, 539 OUT PSUPPORTED_RANGE *Range); 540 541 VOID 542 NTAPI 543 HalpInitBusHandler( 544 VOID 545 ); 546 547 PBUS_HANDLER 548 NTAPI 549 HalpContextToBusHandler( 550 IN ULONG_PTR ContextValue 551 ); 552 553 PBUS_HANDLER 554 FASTCALL 555 HaliReferenceHandlerForConfigSpace( 556 IN BUS_DATA_TYPE ConfigType, 557 IN ULONG BusNumber 558 ); 559 560 ULONG 561 NTAPI 562 HalpNoBusData( 563 IN PBUS_HANDLER BusHandler, 564 IN PBUS_HANDLER RootHandler, 565 IN ULONG SlotNumber, 566 IN PVOID Buffer, 567 IN ULONG Offset, 568 IN ULONG Length 569 ); 570 571 ULONG 572 NTAPI 573 HalpcGetCmosData( 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 582 ULONG 583 NTAPI 584 HalpcSetCmosData( 585 IN PBUS_HANDLER BusHandler, 586 IN PBUS_HANDLER RootHandler, 587 IN ULONG SlotNumber, 588 IN PVOID Buffer, 589 IN ULONG Offset, 590 IN ULONG Length 591 ); 592 593 BOOLEAN 594 NTAPI 595 HalpTranslateSystemBusAddress( 596 IN PBUS_HANDLER BusHandler, 597 IN PBUS_HANDLER RootHandler, 598 IN PHYSICAL_ADDRESS BusAddress, 599 IN OUT PULONG AddressSpace, 600 OUT PPHYSICAL_ADDRESS TranslatedAddress 601 ); 602 603 BOOLEAN 604 NTAPI 605 HalpTranslateIsaBusAddress( 606 IN PBUS_HANDLER BusHandler, 607 IN PBUS_HANDLER RootHandler, 608 IN PHYSICAL_ADDRESS BusAddress, 609 IN OUT PULONG AddressSpace, 610 OUT PPHYSICAL_ADDRESS TranslatedAddress 611 ); 612 613 ULONG 614 NTAPI 615 HalpGetSystemInterruptVector( 616 IN PBUS_HANDLER BusHandler, 617 IN PBUS_HANDLER RootHandler, 618 IN ULONG BusInterruptLevel, 619 IN ULONG BusInterruptVector, 620 OUT PKIRQL Irql, 621 OUT PKAFFINITY Affinity 622 ); 623 624 extern ULONG HalpBusType; 625 extern BOOLEAN HalpPCIConfigInitialized; 626 extern BUS_HANDLER HalpFakePciBusHandler; 627 extern ULONG HalpMinPciBus, HalpMaxPciBus; 628 extern LIST_ENTRY HalpAllBusHandlers; 629 630 /* EOF */ 631