1 /** @file 2 Functions in this library instance make use of MMIO functions in IoLib to 3 access memory mapped PCI configuration space. 4 5 All assertions for I/O operations are handled in MMIO functions in the IoLib 6 Library. 7 8 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved. 9 Portions copyright (c) 2016, American Megatrends, Inc. All rights reserved. 10 This program and the accompanying materials 11 are licensed and made available under the terms and conditions of the BSD License 12 which accompanies this distribution. The full text of the license may be found at 13 http://opensource.org/licenses/bsd-license.php. 14 15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 17 18 **/ 19 20 #include <PiDxe.h> 21 22 #include <Library/BaseLib.h> 23 #include <Library/PciExpressLib.h> 24 #include <Library/IoLib.h> 25 #include <Library/DebugLib.h> 26 #include <Library/PcdLib.h> 27 28 /// 29 /// Module global that contains the base physical address of the PCI Express MMIO range. 30 /// 31 UINTN mSmmPciExpressLibPciExpressBaseAddress = 0; 32 33 /** 34 The constructor function caches the PCI Express Base Address 35 36 @param ImageHandle The firmware allocated handle for the EFI image. 37 @param SystemTable A pointer to the EFI System Table. 38 39 @retval EFI_SUCCESS The constructor completed successfully. 40 **/ 41 EFI_STATUS 42 EFIAPI 43 SmmPciExpressLibConstructor ( 44 IN EFI_HANDLE ImageHandle, 45 IN EFI_SYSTEM_TABLE *SystemTable 46 ) 47 { 48 // 49 // Cache the physical address of the PCI Express MMIO range into a module global variable 50 // 51 mSmmPciExpressLibPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress); 52 53 return EFI_SUCCESS; 54 } 55 56 /** 57 Assert the validity of a PCI address. A valid PCI address should contain 1's 58 only in the low 28 bits. 59 60 @param A The address to validate. 61 62 **/ 63 #define ASSERT_INVALID_PCI_ADDRESS(A) \ 64 ASSERT (((A) & ~0xfffffff) == 0) 65 66 /** 67 Registers a PCI device so PCI configuration registers may be accessed after 68 SetVirtualAddressMap(). 69 70 Registers the PCI device specified by Address so all the PCI configuration 71 registers associated with that PCI device may be accessed after SetVirtualAddressMap() 72 is called. 73 74 If Address > 0x0FFFFFFF, then ASSERT(). 75 76 @param Address The address that encodes the PCI Bus, Device, Function and 77 Register. 78 79 @retval RETURN_SUCCESS The PCI device was registered for runtime access. 80 @retval RETURN_UNSUPPORTED An attempt was made to call this function 81 after ExitBootServices(). 82 @retval RETURN_UNSUPPORTED The resources required to access the PCI device 83 at runtime could not be mapped. 84 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to 85 complete the registration. 86 87 **/ 88 RETURN_STATUS 89 EFIAPI 90 PciExpressRegisterForRuntimeAccess ( 91 IN UINTN Address 92 ) 93 { 94 ASSERT_INVALID_PCI_ADDRESS (Address); 95 return RETURN_UNSUPPORTED; 96 } 97 98 /** 99 Gets MMIO address that can be used to access PCI Express location defined by Address. 100 101 This internal functions converts PCI Express address to a CPU MMIO address by adding 102 PCI Express Base Address stored in a global variable mSmmPciExpressLibPciExpressBaseAddress. 103 mSmmPciExpressLibPciExpressBaseAddress is initialized in the library constructor from PCD entry 104 PcdPciExpressBaseAddress. 105 106 @param Address The address that encodes the PCI Bus, Device, Function and Register. 107 @return MMIO address corresponding to Address. 108 109 **/ 110 UINTN 111 GetPciExpressAddress ( 112 IN UINTN Address 113 ) 114 { 115 // 116 // Make sure Address is valid 117 // 118 ASSERT_INVALID_PCI_ADDRESS (Address); 119 return mSmmPciExpressLibPciExpressBaseAddress + Address; 120 } 121 122 /** 123 Reads an 8-bit PCI configuration register. 124 125 Reads and returns the 8-bit PCI configuration register specified by Address. 126 This function must guarantee that all PCI read and write operations are 127 serialized. 128 129 If Address > 0x0FFFFFFF, then ASSERT(). 130 131 @param Address The address that encodes the PCI Bus, Device, Function and 132 Register. 133 134 @return The read value from the PCI configuration register. 135 136 **/ 137 UINT8 138 EFIAPI 139 PciExpressRead8 ( 140 IN UINTN Address 141 ) 142 { 143 return MmioRead8 (GetPciExpressAddress (Address)); 144 } 145 146 /** 147 Writes an 8-bit PCI configuration register. 148 149 Writes the 8-bit PCI configuration register specified by Address with the 150 value specified by Value. Value is returned. This function must guarantee 151 that all PCI read and write operations are serialized. 152 153 If Address > 0x0FFFFFFF, then ASSERT(). 154 155 @param Address The address that encodes the PCI Bus, Device, Function and 156 Register. 157 @param Value The value to write. 158 159 @return The value written to the PCI configuration register. 160 161 **/ 162 UINT8 163 EFIAPI 164 PciExpressWrite8 ( 165 IN UINTN Address, 166 IN UINT8 Value 167 ) 168 { 169 return MmioWrite8 (GetPciExpressAddress (Address), Value); 170 } 171 172 /** 173 Performs a bitwise OR of an 8-bit PCI configuration register with 174 an 8-bit value. 175 176 Reads the 8-bit PCI configuration register specified by Address, performs a 177 bitwise OR between the read result and the value specified by 178 OrData, and writes the result to the 8-bit PCI configuration register 179 specified by Address. The value written to the PCI configuration register is 180 returned. This function must guarantee that all PCI read and write operations 181 are serialized. 182 183 If Address > 0x0FFFFFFF, then ASSERT(). 184 185 @param Address The address that encodes the PCI Bus, Device, Function and 186 Register. 187 @param OrData The value to OR with the PCI configuration register. 188 189 @return The value written back to the PCI configuration register. 190 191 **/ 192 UINT8 193 EFIAPI 194 PciExpressOr8 ( 195 IN UINTN Address, 196 IN UINT8 OrData 197 ) 198 { 199 return MmioOr8 (GetPciExpressAddress (Address), OrData); 200 } 201 202 /** 203 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit 204 value. 205 206 Reads the 8-bit PCI configuration register specified by Address, performs a 207 bitwise AND between the read result and the value specified by AndData, and 208 writes the result to the 8-bit PCI configuration register specified by 209 Address. The value written to the PCI configuration register is returned. 210 This function must guarantee that all PCI read and write operations are 211 serialized. 212 213 If Address > 0x0FFFFFFF, then ASSERT(). 214 215 @param Address The address that encodes the PCI Bus, Device, Function and 216 Register. 217 @param AndData The value to AND with the PCI configuration register. 218 219 @return The value written back to the PCI configuration register. 220 221 **/ 222 UINT8 223 EFIAPI 224 PciExpressAnd8 ( 225 IN UINTN Address, 226 IN UINT8 AndData 227 ) 228 { 229 return MmioAnd8 (GetPciExpressAddress (Address), AndData); 230 } 231 232 /** 233 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit 234 value, followed a bitwise OR with another 8-bit value. 235 236 Reads the 8-bit PCI configuration register specified by Address, performs a 237 bitwise AND between the read result and the value specified by AndData, 238 performs a bitwise OR between the result of the AND operation and 239 the value specified by OrData, and writes the result to the 8-bit PCI 240 configuration register specified by Address. The value written to the PCI 241 configuration register is returned. This function must guarantee that all PCI 242 read and write operations are serialized. 243 244 If Address > 0x0FFFFFFF, then ASSERT(). 245 246 @param Address The address that encodes the PCI Bus, Device, Function and 247 Register. 248 @param AndData The value to AND with the PCI configuration register. 249 @param OrData The value to OR with the result of the AND operation. 250 251 @return The value written back to the PCI configuration register. 252 253 **/ 254 UINT8 255 EFIAPI 256 PciExpressAndThenOr8 ( 257 IN UINTN Address, 258 IN UINT8 AndData, 259 IN UINT8 OrData 260 ) 261 { 262 return MmioAndThenOr8 ( 263 GetPciExpressAddress (Address), 264 AndData, 265 OrData 266 ); 267 } 268 269 /** 270 Reads a bit field of a PCI configuration register. 271 272 Reads the bit field in an 8-bit PCI configuration register. The bit field is 273 specified by the StartBit and the EndBit. The value of the bit field is 274 returned. 275 276 If Address > 0x0FFFFFFF, then ASSERT(). 277 If StartBit is greater than 7, then ASSERT(). 278 If EndBit is greater than 7, then ASSERT(). 279 If EndBit is less than StartBit, then ASSERT(). 280 281 @param Address The PCI configuration register to read. 282 @param StartBit The ordinal of the least significant bit in the bit field. 283 Range 0..7. 284 @param EndBit The ordinal of the most significant bit in the bit field. 285 Range 0..7. 286 287 @return The value of the bit field read from the PCI configuration register. 288 289 **/ 290 UINT8 291 EFIAPI 292 PciExpressBitFieldRead8 ( 293 IN UINTN Address, 294 IN UINTN StartBit, 295 IN UINTN EndBit 296 ) 297 { 298 return MmioBitFieldRead8 ( 299 GetPciExpressAddress (Address), 300 StartBit, 301 EndBit 302 ); 303 } 304 305 /** 306 Writes a bit field to a PCI configuration register. 307 308 Writes Value to the bit field of the PCI configuration register. The bit 309 field is specified by the StartBit and the EndBit. All other bits in the 310 destination PCI configuration register are preserved. The new value of the 311 8-bit register is returned. 312 313 If Address > 0x0FFFFFFF, then ASSERT(). 314 If StartBit is greater than 7, then ASSERT(). 315 If EndBit is greater than 7, then ASSERT(). 316 If EndBit is less than StartBit, then ASSERT(). 317 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 318 319 @param Address The PCI configuration register to write. 320 @param StartBit The ordinal of the least significant bit in the bit field. 321 Range 0..7. 322 @param EndBit The ordinal of the most significant bit in the bit field. 323 Range 0..7. 324 @param Value The new value of the bit field. 325 326 @return The value written back to the PCI configuration register. 327 328 **/ 329 UINT8 330 EFIAPI 331 PciExpressBitFieldWrite8 ( 332 IN UINTN Address, 333 IN UINTN StartBit, 334 IN UINTN EndBit, 335 IN UINT8 Value 336 ) 337 { 338 return MmioBitFieldWrite8 ( 339 GetPciExpressAddress (Address), 340 StartBit, 341 EndBit, 342 Value 343 ); 344 } 345 346 /** 347 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and 348 writes the result back to the bit field in the 8-bit port. 349 350 Reads the 8-bit PCI configuration register specified by Address, performs a 351 bitwise OR between the read result and the value specified by 352 OrData, and writes the result to the 8-bit PCI configuration register 353 specified by Address. The value written to the PCI configuration register is 354 returned. This function must guarantee that all PCI read and write operations 355 are serialized. Extra left bits in OrData are stripped. 356 357 If Address > 0x0FFFFFFF, then ASSERT(). 358 If StartBit is greater than 7, then ASSERT(). 359 If EndBit is greater than 7, then ASSERT(). 360 If EndBit is less than StartBit, then ASSERT(). 361 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 362 363 @param Address The PCI configuration register to write. 364 @param StartBit The ordinal of the least significant bit in the bit field. 365 Range 0..7. 366 @param EndBit The ordinal of the most significant bit in the bit field. 367 Range 0..7. 368 @param OrData The value to OR with the PCI configuration register. 369 370 @return The value written back to the PCI configuration register. 371 372 **/ 373 UINT8 374 EFIAPI 375 PciExpressBitFieldOr8 ( 376 IN UINTN Address, 377 IN UINTN StartBit, 378 IN UINTN EndBit, 379 IN UINT8 OrData 380 ) 381 { 382 return MmioBitFieldOr8 ( 383 GetPciExpressAddress (Address), 384 StartBit, 385 EndBit, 386 OrData 387 ); 388 } 389 390 /** 391 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise 392 AND, and writes the result back to the bit field in the 8-bit register. 393 394 Reads the 8-bit PCI configuration register specified by Address, performs a 395 bitwise AND between the read result and the value specified by AndData, and 396 writes the result to the 8-bit PCI configuration register specified by 397 Address. The value written to the PCI configuration register is returned. 398 This function must guarantee that all PCI read and write operations are 399 serialized. Extra left bits in AndData are stripped. 400 401 If Address > 0x0FFFFFFF, then ASSERT(). 402 If StartBit is greater than 7, then ASSERT(). 403 If EndBit is greater than 7, then ASSERT(). 404 If EndBit is less than StartBit, then ASSERT(). 405 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 406 407 @param Address The PCI configuration register to write. 408 @param StartBit The ordinal of the least significant bit in the bit field. 409 Range 0..7. 410 @param EndBit The ordinal of the most significant bit in the bit field. 411 Range 0..7. 412 @param AndData The value to AND with the PCI configuration register. 413 414 @return The value written back to the PCI configuration register. 415 416 **/ 417 UINT8 418 EFIAPI 419 PciExpressBitFieldAnd8 ( 420 IN UINTN Address, 421 IN UINTN StartBit, 422 IN UINTN EndBit, 423 IN UINT8 AndData 424 ) 425 { 426 return MmioBitFieldAnd8 ( 427 GetPciExpressAddress (Address), 428 StartBit, 429 EndBit, 430 AndData 431 ); 432 } 433 434 /** 435 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a 436 bitwise OR, and writes the result back to the bit field in the 437 8-bit port. 438 439 Reads the 8-bit PCI configuration register specified by Address, performs a 440 bitwise AND followed by a bitwise OR between the read result and 441 the value specified by AndData, and writes the result to the 8-bit PCI 442 configuration register specified by Address. The value written to the PCI 443 configuration register is returned. This function must guarantee that all PCI 444 read and write operations are serialized. Extra left bits in both AndData and 445 OrData are stripped. 446 447 If Address > 0x0FFFFFFF, then ASSERT(). 448 If StartBit is greater than 7, then ASSERT(). 449 If EndBit is greater than 7, then ASSERT(). 450 If EndBit is less than StartBit, then ASSERT(). 451 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 452 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 453 454 @param Address The PCI configuration register to write. 455 @param StartBit The ordinal of the least significant bit in the bit field. 456 Range 0..7. 457 @param EndBit The ordinal of the most significant bit in the bit field. 458 Range 0..7. 459 @param AndData The value to AND with the PCI configuration register. 460 @param OrData The value to OR with the result of the AND operation. 461 462 @return The value written back to the PCI configuration register. 463 464 **/ 465 UINT8 466 EFIAPI 467 PciExpressBitFieldAndThenOr8 ( 468 IN UINTN Address, 469 IN UINTN StartBit, 470 IN UINTN EndBit, 471 IN UINT8 AndData, 472 IN UINT8 OrData 473 ) 474 { 475 return MmioBitFieldAndThenOr8 ( 476 GetPciExpressAddress (Address), 477 StartBit, 478 EndBit, 479 AndData, 480 OrData 481 ); 482 } 483 484 /** 485 Reads a 16-bit PCI configuration register. 486 487 Reads and returns the 16-bit PCI configuration register specified by Address. 488 This function must guarantee that all PCI read and write operations are 489 serialized. 490 491 If Address > 0x0FFFFFFF, then ASSERT(). 492 If Address is not aligned on a 16-bit boundary, then ASSERT(). 493 494 @param Address The address that encodes the PCI Bus, Device, Function and 495 Register. 496 497 @return The read value from the PCI configuration register. 498 499 **/ 500 UINT16 501 EFIAPI 502 PciExpressRead16 ( 503 IN UINTN Address 504 ) 505 { 506 return MmioRead16 (GetPciExpressAddress (Address)); 507 } 508 509 /** 510 Writes a 16-bit PCI configuration register. 511 512 Writes the 16-bit PCI configuration register specified by Address with the 513 value specified by Value. Value is returned. This function must guarantee 514 that all PCI read and write operations are serialized. 515 516 If Address > 0x0FFFFFFF, then ASSERT(). 517 If Address is not aligned on a 16-bit boundary, then ASSERT(). 518 519 @param Address The address that encodes the PCI Bus, Device, Function and 520 Register. 521 @param Value The value to write. 522 523 @return The value written to the PCI configuration register. 524 525 **/ 526 UINT16 527 EFIAPI 528 PciExpressWrite16 ( 529 IN UINTN Address, 530 IN UINT16 Value 531 ) 532 { 533 return MmioWrite16 (GetPciExpressAddress (Address), Value); 534 } 535 536 /** 537 Performs a bitwise OR of a 16-bit PCI configuration register with 538 a 16-bit value. 539 540 Reads the 16-bit PCI configuration register specified by Address, performs a 541 bitwise OR between the read result and the value specified by 542 OrData, and writes the result to the 16-bit PCI configuration register 543 specified by Address. The value written to the PCI configuration register is 544 returned. This function must guarantee that all PCI read and write operations 545 are serialized. 546 547 If Address > 0x0FFFFFFF, then ASSERT(). 548 If Address is not aligned on a 16-bit boundary, then ASSERT(). 549 550 @param Address The address that encodes the PCI Bus, Device, Function and 551 Register. 552 @param OrData The value to OR with the PCI configuration register. 553 554 @return The value written back to the PCI configuration register. 555 556 **/ 557 UINT16 558 EFIAPI 559 PciExpressOr16 ( 560 IN UINTN Address, 561 IN UINT16 OrData 562 ) 563 { 564 return MmioOr16 (GetPciExpressAddress (Address), OrData); 565 } 566 567 /** 568 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit 569 value. 570 571 Reads the 16-bit PCI configuration register specified by Address, performs a 572 bitwise AND between the read result and the value specified by AndData, and 573 writes the result to the 16-bit PCI configuration register specified by 574 Address. The value written to the PCI configuration register is returned. 575 This function must guarantee that all PCI read and write operations are 576 serialized. 577 578 If Address > 0x0FFFFFFF, then ASSERT(). 579 If Address is not aligned on a 16-bit boundary, then ASSERT(). 580 581 @param Address The address that encodes the PCI Bus, Device, Function and 582 Register. 583 @param AndData The value to AND with the PCI configuration register. 584 585 @return The value written back to the PCI configuration register. 586 587 **/ 588 UINT16 589 EFIAPI 590 PciExpressAnd16 ( 591 IN UINTN Address, 592 IN UINT16 AndData 593 ) 594 { 595 return MmioAnd16 (GetPciExpressAddress (Address), AndData); 596 } 597 598 /** 599 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit 600 value, followed a bitwise OR with another 16-bit value. 601 602 Reads the 16-bit PCI configuration register specified by Address, performs a 603 bitwise AND between the read result and the value specified by AndData, 604 performs a bitwise OR between the result of the AND operation and 605 the value specified by OrData, and writes the result to the 16-bit PCI 606 configuration register specified by Address. The value written to the PCI 607 configuration register is returned. This function must guarantee that all PCI 608 read and write operations are serialized. 609 610 If Address > 0x0FFFFFFF, then ASSERT(). 611 If Address is not aligned on a 16-bit boundary, then ASSERT(). 612 613 @param Address The address that encodes the PCI Bus, Device, Function and 614 Register. 615 @param AndData The value to AND with the PCI configuration register. 616 @param OrData The value to OR with the result of the AND operation. 617 618 @return The value written back to the PCI configuration register. 619 620 **/ 621 UINT16 622 EFIAPI 623 PciExpressAndThenOr16 ( 624 IN UINTN Address, 625 IN UINT16 AndData, 626 IN UINT16 OrData 627 ) 628 { 629 return MmioAndThenOr16 ( 630 GetPciExpressAddress (Address), 631 AndData, 632 OrData 633 ); 634 } 635 636 /** 637 Reads a bit field of a PCI configuration register. 638 639 Reads the bit field in a 16-bit PCI configuration register. The bit field is 640 specified by the StartBit and the EndBit. The value of the bit field is 641 returned. 642 643 If Address > 0x0FFFFFFF, then ASSERT(). 644 If Address is not aligned on a 16-bit boundary, then ASSERT(). 645 If StartBit is greater than 15, then ASSERT(). 646 If EndBit is greater than 15, then ASSERT(). 647 If EndBit is less than StartBit, then ASSERT(). 648 649 @param Address The PCI configuration register to read. 650 @param StartBit The ordinal of the least significant bit in the bit field. 651 Range 0..15. 652 @param EndBit The ordinal of the most significant bit in the bit field. 653 Range 0..15. 654 655 @return The value of the bit field read from the PCI configuration register. 656 657 **/ 658 UINT16 659 EFIAPI 660 PciExpressBitFieldRead16 ( 661 IN UINTN Address, 662 IN UINTN StartBit, 663 IN UINTN EndBit 664 ) 665 { 666 return MmioBitFieldRead16 ( 667 GetPciExpressAddress (Address), 668 StartBit, 669 EndBit 670 ); 671 } 672 673 /** 674 Writes a bit field to a PCI configuration register. 675 676 Writes Value to the bit field of the PCI configuration register. The bit 677 field is specified by the StartBit and the EndBit. All other bits in the 678 destination PCI configuration register are preserved. The new value of the 679 16-bit register is returned. 680 681 If Address > 0x0FFFFFFF, then ASSERT(). 682 If Address is not aligned on a 16-bit boundary, then ASSERT(). 683 If StartBit is greater than 15, then ASSERT(). 684 If EndBit is greater than 15, then ASSERT(). 685 If EndBit is less than StartBit, then ASSERT(). 686 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 687 688 @param Address The PCI configuration register to write. 689 @param StartBit The ordinal of the least significant bit in the bit field. 690 Range 0..15. 691 @param EndBit The ordinal of the most significant bit in the bit field. 692 Range 0..15. 693 @param Value The new value of the bit field. 694 695 @return The value written back to the PCI configuration register. 696 697 **/ 698 UINT16 699 EFIAPI 700 PciExpressBitFieldWrite16 ( 701 IN UINTN Address, 702 IN UINTN StartBit, 703 IN UINTN EndBit, 704 IN UINT16 Value 705 ) 706 { 707 return MmioBitFieldWrite16 ( 708 GetPciExpressAddress (Address), 709 StartBit, 710 EndBit, 711 Value 712 ); 713 } 714 715 /** 716 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and 717 writes the result back to the bit field in the 16-bit port. 718 719 Reads the 16-bit PCI configuration register specified by Address, performs a 720 bitwise OR between the read result and the value specified by 721 OrData, and writes the result to the 16-bit PCI configuration register 722 specified by Address. The value written to the PCI configuration register is 723 returned. This function must guarantee that all PCI read and write operations 724 are serialized. Extra left bits in OrData are stripped. 725 726 If Address > 0x0FFFFFFF, then ASSERT(). 727 If Address is not aligned on a 16-bit boundary, then ASSERT(). 728 If StartBit is greater than 15, then ASSERT(). 729 If EndBit is greater than 15, then ASSERT(). 730 If EndBit is less than StartBit, then ASSERT(). 731 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 732 733 @param Address The PCI configuration register to write. 734 @param StartBit The ordinal of the least significant bit in the bit field. 735 Range 0..15. 736 @param EndBit The ordinal of the most significant bit in the bit field. 737 Range 0..15. 738 @param OrData The value to OR with the PCI configuration register. 739 740 @return The value written back to the PCI configuration register. 741 742 **/ 743 UINT16 744 EFIAPI 745 PciExpressBitFieldOr16 ( 746 IN UINTN Address, 747 IN UINTN StartBit, 748 IN UINTN EndBit, 749 IN UINT16 OrData 750 ) 751 { 752 return MmioBitFieldOr16 ( 753 GetPciExpressAddress (Address), 754 StartBit, 755 EndBit, 756 OrData 757 ); 758 } 759 760 /** 761 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise 762 AND, and writes the result back to the bit field in the 16-bit register. 763 764 Reads the 16-bit PCI configuration register specified by Address, performs a 765 bitwise AND between the read result and the value specified by AndData, and 766 writes the result to the 16-bit PCI configuration register specified by 767 Address. The value written to the PCI configuration register is returned. 768 This function must guarantee that all PCI read and write operations are 769 serialized. Extra left bits in AndData are stripped. 770 771 If Address > 0x0FFFFFFF, then ASSERT(). 772 If Address is not aligned on a 16-bit boundary, then ASSERT(). 773 If StartBit is greater than 15, then ASSERT(). 774 If EndBit is greater than 15, then ASSERT(). 775 If EndBit is less than StartBit, then ASSERT(). 776 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 777 778 @param Address The PCI configuration register to write. 779 @param StartBit The ordinal of the least significant bit in the bit field. 780 Range 0..15. 781 @param EndBit The ordinal of the most significant bit in the bit field. 782 Range 0..15. 783 @param AndData The value to AND with the PCI configuration register. 784 785 @return The value written back to the PCI configuration register. 786 787 **/ 788 UINT16 789 EFIAPI 790 PciExpressBitFieldAnd16 ( 791 IN UINTN Address, 792 IN UINTN StartBit, 793 IN UINTN EndBit, 794 IN UINT16 AndData 795 ) 796 { 797 return MmioBitFieldAnd16 ( 798 GetPciExpressAddress (Address), 799 StartBit, 800 EndBit, 801 AndData 802 ); 803 } 804 805 /** 806 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a 807 bitwise OR, and writes the result back to the bit field in the 808 16-bit port. 809 810 Reads the 16-bit PCI configuration register specified by Address, performs a 811 bitwise AND followed by a bitwise OR between the read result and 812 the value specified by AndData, and writes the result to the 16-bit PCI 813 configuration register specified by Address. The value written to the PCI 814 configuration register is returned. This function must guarantee that all PCI 815 read and write operations are serialized. Extra left bits in both AndData and 816 OrData are stripped. 817 818 If Address > 0x0FFFFFFF, then ASSERT(). 819 If Address is not aligned on a 16-bit boundary, then ASSERT(). 820 If StartBit is greater than 15, then ASSERT(). 821 If EndBit is greater than 15, then ASSERT(). 822 If EndBit is less than StartBit, then ASSERT(). 823 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 824 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 825 826 @param Address The PCI configuration register to write. 827 @param StartBit The ordinal of the least significant bit in the bit field. 828 Range 0..15. 829 @param EndBit The ordinal of the most significant bit in the bit field. 830 Range 0..15. 831 @param AndData The value to AND with the PCI configuration register. 832 @param OrData The value to OR with the result of the AND operation. 833 834 @return The value written back to the PCI configuration register. 835 836 **/ 837 UINT16 838 EFIAPI 839 PciExpressBitFieldAndThenOr16 ( 840 IN UINTN Address, 841 IN UINTN StartBit, 842 IN UINTN EndBit, 843 IN UINT16 AndData, 844 IN UINT16 OrData 845 ) 846 { 847 return MmioBitFieldAndThenOr16 ( 848 GetPciExpressAddress (Address), 849 StartBit, 850 EndBit, 851 AndData, 852 OrData 853 ); 854 } 855 856 /** 857 Reads a 32-bit PCI configuration register. 858 859 Reads and returns the 32-bit PCI configuration register specified by Address. 860 This function must guarantee that all PCI read and write operations are 861 serialized. 862 863 If Address > 0x0FFFFFFF, then ASSERT(). 864 If Address is not aligned on a 32-bit boundary, then ASSERT(). 865 866 @param Address The address that encodes the PCI Bus, Device, Function and 867 Register. 868 869 @return The read value from the PCI configuration register. 870 871 **/ 872 UINT32 873 EFIAPI 874 PciExpressRead32 ( 875 IN UINTN Address 876 ) 877 { 878 return MmioRead32 (GetPciExpressAddress (Address)); 879 } 880 881 /** 882 Writes a 32-bit PCI configuration register. 883 884 Writes the 32-bit PCI configuration register specified by Address with the 885 value specified by Value. Value is returned. This function must guarantee 886 that all PCI read and write operations are serialized. 887 888 If Address > 0x0FFFFFFF, then ASSERT(). 889 If Address is not aligned on a 32-bit boundary, then ASSERT(). 890 891 @param Address The address that encodes the PCI Bus, Device, Function and 892 Register. 893 @param Value The value to write. 894 895 @return The value written to the PCI configuration register. 896 897 **/ 898 UINT32 899 EFIAPI 900 PciExpressWrite32 ( 901 IN UINTN Address, 902 IN UINT32 Value 903 ) 904 { 905 return MmioWrite32 (GetPciExpressAddress (Address), Value); 906 } 907 908 /** 909 Performs a bitwise OR of a 32-bit PCI configuration register with 910 a 32-bit value. 911 912 Reads the 32-bit PCI configuration register specified by Address, performs a 913 bitwise OR between the read result and the value specified by 914 OrData, and writes the result to the 32-bit PCI configuration register 915 specified by Address. The value written to the PCI configuration register is 916 returned. This function must guarantee that all PCI read and write operations 917 are serialized. 918 919 If Address > 0x0FFFFFFF, then ASSERT(). 920 If Address is not aligned on a 32-bit boundary, then ASSERT(). 921 922 @param Address The address that encodes the PCI Bus, Device, Function and 923 Register. 924 @param OrData The value to OR with the PCI configuration register. 925 926 @return The value written back to the PCI configuration register. 927 928 **/ 929 UINT32 930 EFIAPI 931 PciExpressOr32 ( 932 IN UINTN Address, 933 IN UINT32 OrData 934 ) 935 { 936 return MmioOr32 (GetPciExpressAddress (Address), OrData); 937 } 938 939 /** 940 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit 941 value. 942 943 Reads the 32-bit PCI configuration register specified by Address, performs a 944 bitwise AND between the read result and the value specified by AndData, and 945 writes the result to the 32-bit PCI configuration register specified by 946 Address. The value written to the PCI configuration register is returned. 947 This function must guarantee that all PCI read and write operations are 948 serialized. 949 950 If Address > 0x0FFFFFFF, then ASSERT(). 951 If Address is not aligned on a 32-bit boundary, then ASSERT(). 952 953 @param Address The address that encodes the PCI Bus, Device, Function and 954 Register. 955 @param AndData The value to AND with the PCI configuration register. 956 957 @return The value written back to the PCI configuration register. 958 959 **/ 960 UINT32 961 EFIAPI 962 PciExpressAnd32 ( 963 IN UINTN Address, 964 IN UINT32 AndData 965 ) 966 { 967 return MmioAnd32 (GetPciExpressAddress (Address), AndData); 968 } 969 970 /** 971 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit 972 value, followed a bitwise OR with another 32-bit value. 973 974 Reads the 32-bit PCI configuration register specified by Address, performs a 975 bitwise AND between the read result and the value specified by AndData, 976 performs a bitwise OR between the result of the AND operation and 977 the value specified by OrData, and writes the result to the 32-bit PCI 978 configuration register specified by Address. The value written to the PCI 979 configuration register is returned. This function must guarantee that all PCI 980 read and write operations are serialized. 981 982 If Address > 0x0FFFFFFF, then ASSERT(). 983 If Address is not aligned on a 32-bit boundary, then ASSERT(). 984 985 @param Address The address that encodes the PCI Bus, Device, Function and 986 Register. 987 @param AndData The value to AND with the PCI configuration register. 988 @param OrData The value to OR with the result of the AND operation. 989 990 @return The value written back to the PCI configuration register. 991 992 **/ 993 UINT32 994 EFIAPI 995 PciExpressAndThenOr32 ( 996 IN UINTN Address, 997 IN UINT32 AndData, 998 IN UINT32 OrData 999 ) 1000 { 1001 return MmioAndThenOr32 ( 1002 GetPciExpressAddress (Address), 1003 AndData, 1004 OrData 1005 ); 1006 } 1007 1008 /** 1009 Reads a bit field of a PCI configuration register. 1010 1011 Reads the bit field in a 32-bit PCI configuration register. The bit field is 1012 specified by the StartBit and the EndBit. The value of the bit field is 1013 returned. 1014 1015 If Address > 0x0FFFFFFF, then ASSERT(). 1016 If Address is not aligned on a 32-bit boundary, then ASSERT(). 1017 If StartBit is greater than 31, then ASSERT(). 1018 If EndBit is greater than 31, then ASSERT(). 1019 If EndBit is less than StartBit, then ASSERT(). 1020 1021 @param Address The PCI configuration register to read. 1022 @param StartBit The ordinal of the least significant bit in the bit field. 1023 Range 0..31. 1024 @param EndBit The ordinal of the most significant bit in the bit field. 1025 Range 0..31. 1026 1027 @return The value of the bit field read from the PCI configuration register. 1028 1029 **/ 1030 UINT32 1031 EFIAPI 1032 PciExpressBitFieldRead32 ( 1033 IN UINTN Address, 1034 IN UINTN StartBit, 1035 IN UINTN EndBit 1036 ) 1037 { 1038 return MmioBitFieldRead32 ( 1039 GetPciExpressAddress (Address), 1040 StartBit, 1041 EndBit 1042 ); 1043 } 1044 1045 /** 1046 Writes a bit field to a PCI configuration register. 1047 1048 Writes Value to the bit field of the PCI configuration register. The bit 1049 field is specified by the StartBit and the EndBit. All other bits in the 1050 destination PCI configuration register are preserved. The new value of the 1051 32-bit register is returned. 1052 1053 If Address > 0x0FFFFFFF, then ASSERT(). 1054 If Address is not aligned on a 32-bit boundary, then ASSERT(). 1055 If StartBit is greater than 31, then ASSERT(). 1056 If EndBit is greater than 31, then ASSERT(). 1057 If EndBit is less than StartBit, then ASSERT(). 1058 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 1059 1060 @param Address The PCI configuration register to write. 1061 @param StartBit The ordinal of the least significant bit in the bit field. 1062 Range 0..31. 1063 @param EndBit The ordinal of the most significant bit in the bit field. 1064 Range 0..31. 1065 @param Value The new value of the bit field. 1066 1067 @return The value written back to the PCI configuration register. 1068 1069 **/ 1070 UINT32 1071 EFIAPI 1072 PciExpressBitFieldWrite32 ( 1073 IN UINTN Address, 1074 IN UINTN StartBit, 1075 IN UINTN EndBit, 1076 IN UINT32 Value 1077 ) 1078 { 1079 return MmioBitFieldWrite32 ( 1080 GetPciExpressAddress (Address), 1081 StartBit, 1082 EndBit, 1083 Value 1084 ); 1085 } 1086 1087 /** 1088 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and 1089 writes the result back to the bit field in the 32-bit port. 1090 1091 Reads the 32-bit PCI configuration register specified by Address, performs a 1092 bitwise OR between the read result and the value specified by 1093 OrData, and writes the result to the 32-bit PCI configuration register 1094 specified by Address. The value written to the PCI configuration register is 1095 returned. This function must guarantee that all PCI read and write operations 1096 are serialized. Extra left bits in OrData are stripped. 1097 1098 If Address > 0x0FFFFFFF, then ASSERT(). 1099 If Address is not aligned on a 32-bit boundary, then ASSERT(). 1100 If StartBit is greater than 31, then ASSERT(). 1101 If EndBit is greater than 31, then ASSERT(). 1102 If EndBit is less than StartBit, then ASSERT(). 1103 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 1104 1105 @param Address The PCI configuration register to write. 1106 @param StartBit The ordinal of the least significant bit in the bit field. 1107 Range 0..31. 1108 @param EndBit The ordinal of the most significant bit in the bit field. 1109 Range 0..31. 1110 @param OrData The value to OR with the PCI configuration register. 1111 1112 @return The value written back to the PCI configuration register. 1113 1114 **/ 1115 UINT32 1116 EFIAPI 1117 PciExpressBitFieldOr32 ( 1118 IN UINTN Address, 1119 IN UINTN StartBit, 1120 IN UINTN EndBit, 1121 IN UINT32 OrData 1122 ) 1123 { 1124 return MmioBitFieldOr32 ( 1125 GetPciExpressAddress (Address), 1126 StartBit, 1127 EndBit, 1128 OrData 1129 ); 1130 } 1131 1132 /** 1133 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise 1134 AND, and writes the result back to the bit field in the 32-bit register. 1135 1136 Reads the 32-bit PCI configuration register specified by Address, performs a 1137 bitwise AND between the read result and the value specified by AndData, and 1138 writes the result to the 32-bit PCI configuration register specified by 1139 Address. The value written to the PCI configuration register is returned. 1140 This function must guarantee that all PCI read and write operations are 1141 serialized. Extra left bits in AndData are stripped. 1142 1143 If Address > 0x0FFFFFFF, then ASSERT(). 1144 If Address is not aligned on a 32-bit boundary, then ASSERT(). 1145 If StartBit is greater than 31, then ASSERT(). 1146 If EndBit is greater than 31, then ASSERT(). 1147 If EndBit is less than StartBit, then ASSERT(). 1148 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 1149 1150 @param Address The PCI configuration register to write. 1151 @param StartBit The ordinal of the least significant bit in the bit field. 1152 Range 0..31. 1153 @param EndBit The ordinal of the most significant bit in the bit field. 1154 Range 0..31. 1155 @param AndData The value to AND with the PCI configuration register. 1156 1157 @return The value written back to the PCI configuration register. 1158 1159 **/ 1160 UINT32 1161 EFIAPI 1162 PciExpressBitFieldAnd32 ( 1163 IN UINTN Address, 1164 IN UINTN StartBit, 1165 IN UINTN EndBit, 1166 IN UINT32 AndData 1167 ) 1168 { 1169 return MmioBitFieldAnd32 ( 1170 GetPciExpressAddress (Address), 1171 StartBit, 1172 EndBit, 1173 AndData 1174 ); 1175 } 1176 1177 /** 1178 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a 1179 bitwise OR, and writes the result back to the bit field in the 1180 32-bit port. 1181 1182 Reads the 32-bit PCI configuration register specified by Address, performs a 1183 bitwise AND followed by a bitwise OR between the read result and 1184 the value specified by AndData, and writes the result to the 32-bit PCI 1185 configuration register specified by Address. The value written to the PCI 1186 configuration register is returned. This function must guarantee that all PCI 1187 read and write operations are serialized. Extra left bits in both AndData and 1188 OrData are stripped. 1189 1190 If Address > 0x0FFFFFFF, then ASSERT(). 1191 If Address is not aligned on a 32-bit boundary, then ASSERT(). 1192 If StartBit is greater than 31, then ASSERT(). 1193 If EndBit is greater than 31, then ASSERT(). 1194 If EndBit is less than StartBit, then ASSERT(). 1195 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 1196 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). 1197 1198 @param Address The PCI configuration register to write. 1199 @param StartBit The ordinal of the least significant bit in the bit field. 1200 Range 0..31. 1201 @param EndBit The ordinal of the most significant bit in the bit field. 1202 Range 0..31. 1203 @param AndData The value to AND with the PCI configuration register. 1204 @param OrData The value to OR with the result of the AND operation. 1205 1206 @return The value written back to the PCI configuration register. 1207 1208 **/ 1209 UINT32 1210 EFIAPI 1211 PciExpressBitFieldAndThenOr32 ( 1212 IN UINTN Address, 1213 IN UINTN StartBit, 1214 IN UINTN EndBit, 1215 IN UINT32 AndData, 1216 IN UINT32 OrData 1217 ) 1218 { 1219 return MmioBitFieldAndThenOr32 ( 1220 GetPciExpressAddress (Address), 1221 StartBit, 1222 EndBit, 1223 AndData, 1224 OrData 1225 ); 1226 } 1227 1228 /** 1229 Reads a range of PCI configuration registers into a caller supplied buffer. 1230 1231 Reads the range of PCI configuration registers specified by StartAddress and 1232 Size into the buffer specified by Buffer. This function only allows the PCI 1233 configuration registers from a single PCI function to be read. Size is 1234 returned. When possible 32-bit PCI configuration read cycles are used to read 1235 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit 1236 and 16-bit PCI configuration read cycles may be used at the beginning and the 1237 end of the range. 1238 1239 If StartAddress > 0x0FFFFFFF, then ASSERT(). 1240 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). 1241 If Size > 0 and Buffer is NULL, then ASSERT(). 1242 1243 @param StartAddress The starting address that encodes the PCI Bus, Device, 1244 Function and Register. 1245 @param Size The size in bytes of the transfer. 1246 @param Buffer The pointer to a buffer receiving the data read. 1247 1248 @return Size read data from StartAddress. 1249 1250 **/ 1251 UINTN 1252 EFIAPI 1253 PciExpressReadBuffer ( 1254 IN UINTN StartAddress, 1255 IN UINTN Size, 1256 OUT VOID *Buffer 1257 ) 1258 { 1259 UINTN ReturnValue; 1260 1261 // 1262 // Make sure Address is valid 1263 // 1264 ASSERT_INVALID_PCI_ADDRESS (StartAddress); 1265 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); 1266 1267 if (Size == 0) { 1268 return Size; 1269 } 1270 1271 ASSERT (Buffer != NULL); 1272 1273 // 1274 // Save Size for return 1275 // 1276 ReturnValue = Size; 1277 1278 if ((StartAddress & 1) != 0) { 1279 // 1280 // Read a byte if StartAddress is byte aligned 1281 // 1282 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); 1283 StartAddress += sizeof (UINT8); 1284 Size -= sizeof (UINT8); 1285 Buffer = (UINT8*)Buffer + 1; 1286 } 1287 1288 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { 1289 // 1290 // Read a word if StartAddress is word aligned 1291 // 1292 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress)); 1293 1294 StartAddress += sizeof (UINT16); 1295 Size -= sizeof (UINT16); 1296 Buffer = (UINT16*)Buffer + 1; 1297 } 1298 1299 while (Size >= sizeof (UINT32)) { 1300 // 1301 // Read as many double words as possible 1302 // 1303 WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress)); 1304 1305 StartAddress += sizeof (UINT32); 1306 Size -= sizeof (UINT32); 1307 Buffer = (UINT32*)Buffer + 1; 1308 } 1309 1310 if (Size >= sizeof (UINT16)) { 1311 // 1312 // Read the last remaining word if exist 1313 // 1314 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress)); 1315 StartAddress += sizeof (UINT16); 1316 Size -= sizeof (UINT16); 1317 Buffer = (UINT16*)Buffer + 1; 1318 } 1319 1320 if (Size >= sizeof (UINT8)) { 1321 // 1322 // Read the last remaining byte if exist 1323 // 1324 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); 1325 } 1326 1327 return ReturnValue; 1328 } 1329 1330 /** 1331 Copies the data in a caller supplied buffer to a specified range of PCI 1332 configuration space. 1333 1334 Writes the range of PCI configuration registers specified by StartAddress and 1335 Size from the buffer specified by Buffer. This function only allows the PCI 1336 configuration registers from a single PCI function to be written. Size is 1337 returned. When possible 32-bit PCI configuration write cycles are used to 1338 write from StartAdress to StartAddress + Size. Due to alignment restrictions, 1339 8-bit and 16-bit PCI configuration write cycles may be used at the beginning 1340 and the end of the range. 1341 1342 If StartAddress > 0x0FFFFFFF, then ASSERT(). 1343 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). 1344 If Size > 0 and Buffer is NULL, then ASSERT(). 1345 1346 @param StartAddress The starting address that encodes the PCI Bus, Device, 1347 Function and Register. 1348 @param Size The size in bytes of the transfer. 1349 @param Buffer The pointer to a buffer containing the data to write. 1350 1351 @return Size written to StartAddress. 1352 1353 **/ 1354 UINTN 1355 EFIAPI 1356 PciExpressWriteBuffer ( 1357 IN UINTN StartAddress, 1358 IN UINTN Size, 1359 IN VOID *Buffer 1360 ) 1361 { 1362 UINTN ReturnValue; 1363 1364 // 1365 // Make sure Address is valid 1366 // 1367 ASSERT_INVALID_PCI_ADDRESS (StartAddress); 1368 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); 1369 1370 1371 if (Size == 0) { 1372 return 0; 1373 } 1374 1375 ASSERT (Buffer != NULL); 1376 1377 // 1378 // Save Size for return 1379 // 1380 ReturnValue = Size; 1381 1382 if ((StartAddress & 1) != 0) { 1383 // 1384 // Write a byte if StartAddress is byte aligned 1385 // 1386 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); 1387 StartAddress += sizeof (UINT8); 1388 Size -= sizeof (UINT8); 1389 Buffer = (UINT8*)Buffer + 1; 1390 } 1391 1392 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { 1393 // 1394 // Write a word if StartAddress is word aligned 1395 // 1396 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)); 1397 StartAddress += sizeof (UINT16); 1398 Size -= sizeof (UINT16); 1399 Buffer = (UINT16*)Buffer + 1; 1400 } 1401 1402 while (Size >= sizeof (UINT32)) { 1403 // 1404 // Write as many double words as possible 1405 // 1406 PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer)); 1407 StartAddress += sizeof (UINT32); 1408 Size -= sizeof (UINT32); 1409 Buffer = (UINT32*)Buffer + 1; 1410 } 1411 1412 if (Size >= sizeof (UINT16)) { 1413 // 1414 // Write the last remaining word if exist 1415 // 1416 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)); 1417 StartAddress += sizeof (UINT16); 1418 Size -= sizeof (UINT16); 1419 Buffer = (UINT16*)Buffer + 1; 1420 } 1421 1422 if (Size >= sizeof (UINT8)) { 1423 // 1424 // Write the last remaining byte if exist 1425 // 1426 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); 1427 } 1428 1429 return ReturnValue; 1430 } 1431