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