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