]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BasePciCf8Lib / PciCf8Lib.c
index 2754d305607498fc7ddfcab10ab34246b82cd46d..ba4190ab686cb9235fb7a9616799586d2f9ee3ee 100644 (file)
@@ -2,14 +2,8 @@
   PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.\r
   Layers on top of an I/O Library instance.\r
 \r
-  Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8\r
 #define PCI_CONFIGURATION_DATA_PORT     0xCFC\r
 \r
-//\r
-// Declare macro to convert PCI Library formatted address to CF8 formatted address\r
-//\r
-// PCI Library formatted address    CF8 Formatted Address\r
-// =============================    ======================\r
-//    Bits 00..11  Register           Bits 00..07  Register\r
-//    Bits 12..14  Function           Bits 08..10  Function\r
-//    Bits 15..19  Device             Bits 11..15  Device\r
-//    Bits 20..27  Bus                Bits 16..23  Bus\r
-//    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)\r
-//                                    Bits 31..31  Must be 1\r
-//\r
+/**\r
+  Convert a PCI Library address to PCI CF8 formatted address.\r
+\r
+  Declare macro to convert PCI Library address to PCI CF8 formatted address.\r
+  Bit fields of PCI Library and CF8 formatted address is as follows:\r
+  PCI Library formatted address    CF8 Formatted Address\r
+ =============================    ======================\r
+    Bits 00..11  Register           Bits 00..07  Register\r
+    Bits 12..14  Function           Bits 08..10  Function\r
+    Bits 15..19  Device             Bits 11..15  Device\r
+    Bits 20..27  Bus                Bits 16..23  Bus\r
+    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)\r
+                                    Bits 31..31  Must be 1\r
+\r
+  @param  A The address to convert.\r
+\r
+  @retval The coverted address.\r
+\r
+**/\r
+#define PCI_TO_CF8_ADDRESS(A) \\r
+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))\r
 \r
 /**\r
-  Assert the validity of a PCI address. A valid PCI address should contain 1's\r
-  only in the low 28 bits.\r
+  Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's\r
+  only in the low 28 bits, excluding bits 08..11.\r
 \r
   @param  A The address to validate.\r
   @param  M Additional bits to assert to be zero.\r
   ASSERT (((A) & (~0xffff0ff | (M))) == 0)\r
 \r
 /**\r
-  Convert a PCI Express address to PCI CF8 address.\r
+  Registers a PCI device so PCI configuration registers may be accessed after\r
+  SetVirtualAddressMap().\r
 \r
-  @param  A The address to convert.\r
+  Registers the PCI device specified by Address so all the PCI configuration registers\r
+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.\r
 \r
-  @retval The coverted address.\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If the register specified by Address >= 0x100, then ASSERT().\r
+\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+\r
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.\r
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function\r
+                                   after ExitBootServices().\r
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device\r
+                                   at runtime could not be mapped.\r
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to\r
+                                   complete the registration.\r
 \r
 **/\r
-#define PCI_TO_CF8_ADDRESS(A) \\r
-  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))\r
+RETURN_STATUS\r
+EFIAPI\r
+PciCf8RegisterForRuntimeAccess (\r
+  IN UINTN  Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  return RETURN_SUCCESS;\r
+}\r
 \r
 /**\r
   Reads an 8-bit PCI configuration register.\r
@@ -72,7 +96,7 @@
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
 \r
   @return The read value from the PCI configuration register.\r
@@ -84,9 +108,18 @@ PciCf8Read8 (
   IN      UINTN                     Address\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));\r
+  Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -99,7 +132,7 @@ PciCf8Read8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  Value   The value to write.\r
 \r
@@ -113,20 +146,29 @@ PciCf8Write8 (
   IN      UINT8                     Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoWrite8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           Value\r
-           );\r
+  Result = IoWrite8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
-  Performs a bitwise inclusive OR of an 8-bit PCI configuration register with\r
+  Performs a bitwise OR of an 8-bit PCI configuration register with\r
   an 8-bit value.\r
 \r
   Reads the 8-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 8-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -135,7 +177,7 @@ PciCf8Write8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  OrData  The value to OR with the PCI configuration register.\r
 \r
@@ -149,12 +191,21 @@ PciCf8Or8 (
   IN      UINT8                     OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoOr8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           OrData\r
-           );\r
+  Result = IoOr8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -171,7 +222,7 @@ PciCf8Or8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
 \r
@@ -185,21 +236,30 @@ PciCf8And8 (
   IN      UINT8                     AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAnd8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           AndData\r
-           );\r
+  Result = IoAnd8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
-  value, followed a  bitwise inclusive OR with another 8-bit value.\r
+  value, followed a  bitwise OR with another 8-bit value.\r
 \r
   Reads the 8-bit PCI configuration register specified by Address, performs a\r
   bitwise AND between the read result and the value specified by AndData,\r
-  performs a bitwise inclusive OR between the result of the AND operation and\r
+  performs a bitwise OR between the result of the AND operation and\r
   the value specified by OrData, and writes the result to the 8-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -208,7 +268,7 @@ PciCf8And8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
   @param  OrData  The value to OR with the result of the AND operation.\r
@@ -224,13 +284,22 @@ PciCf8AndThenOr8 (
   IN      UINT8                     OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAndThenOr8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoAndThenOr8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             AndData,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -246,7 +315,7 @@ PciCf8AndThenOr8 (
   If EndBit is greater than 7, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to read.\r
+  @param  Address   The PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..7.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -263,13 +332,22 @@ PciCf8BitFieldRead8 (
   IN      UINTN                     EndBit\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldRead8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           StartBit,\r
-           EndBit\r
-           );\r
+  Result = IoBitFieldRead8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             StartBit,\r
+             EndBit\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -285,13 +363,14 @@ PciCf8BitFieldRead8 (
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..7.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
                     Range 0..7.\r
-  @param  Value     New value of the bit field.\r
+  @param  Value     The new value of the bit field.\r
 \r
   @return The value written back to the PCI configuration register.\r
 \r
@@ -305,14 +384,23 @@ PciCf8BitFieldWrite8 (
   IN      UINT8                     Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldWrite8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           StartBit,\r
-           EndBit,\r
-           Value\r
-           );\r
+  Result = IoBitFieldWrite8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             StartBit,\r
+             EndBit,\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -320,7 +408,7 @@ PciCf8BitFieldWrite8 (
   writes the result back to the bit field in the 8-bit port.\r
 \r
   Reads the 8-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 8-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -331,8 +419,9 @@ PciCf8BitFieldWrite8 (
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..7.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -351,14 +440,23 @@ PciCf8BitFieldOr8 (
   IN      UINT8                     OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldOr8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           StartBit,\r
-           EndBit,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldOr8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             StartBit,\r
+             EndBit,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -377,8 +475,9 @@ PciCf8BitFieldOr8 (
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..7.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -397,23 +496,32 @@ PciCf8BitFieldAnd8 (
   IN      UINT8                     AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAnd8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           StartBit,\r
-           EndBit,\r
-           AndData\r
-           );\r
+  Result = IoBitFieldAnd8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             StartBit,\r
+             EndBit,\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
-  bitwise inclusive OR, and writes the result back to the bit field in the\r
+  bitwise OR, and writes the result back to the bit field in the\r
   8-bit port.\r
 \r
   Reads the 8-bit PCI configuration register specified by Address, performs a\r
-  bitwise AND followed by a bitwise inclusive OR between the read result and\r
+  bitwise AND followed by a bitwise OR between the read result and\r
   the value specified by AndData, and writes the result to the 8-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -425,8 +533,10 @@ PciCf8BitFieldAnd8 (
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..7.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -447,15 +557,24 @@ PciCf8BitFieldAndThenOr8(
   IN      UINT8                     OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT8    Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAndThenOr8 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
-           StartBit,\r
-           EndBit,\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldAndThenOr8 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
+             StartBit,\r
+             EndBit,\r
+             AndData,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -469,7 +588,7 @@ PciCf8BitFieldAndThenOr8(
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
 \r
   @return The read value from the PCI configuration register.\r
@@ -481,9 +600,18 @@ PciCf8Read16 (
   IN      UINTN                     Address\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));\r
+  Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -497,7 +625,7 @@ PciCf8Read16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  Value   The value to write.\r
 \r
@@ -511,20 +639,29 @@ PciCf8Write16 (
   IN      UINT16                    Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoWrite16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           Value\r
-           );\r
+  Result = IoWrite16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
-  Performs a bitwise inclusive OR of a 16-bit PCI configuration register with\r
+  Performs a bitwise OR of a 16-bit PCI configuration register with\r
   a 16-bit value.\r
 \r
   Reads the 16-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 16-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -534,7 +671,7 @@ PciCf8Write16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  OrData  The value to OR with the PCI configuration register.\r
 \r
@@ -548,12 +685,21 @@ PciCf8Or16 (
   IN      UINT16                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoOr16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           OrData\r
-           );\r
+  Result = IoOr16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -571,7 +717,7 @@ PciCf8Or16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
 \r
@@ -585,21 +731,30 @@ PciCf8And16 (
   IN      UINT16                    AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAnd16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           AndData\r
-           );\r
+  Result = IoAnd16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
-  value, followed a  bitwise inclusive OR with another 16-bit value.\r
+  value, followed a  bitwise OR with another 16-bit value.\r
 \r
   Reads the 16-bit PCI configuration register specified by Address, performs a\r
   bitwise AND between the read result and the value specified by AndData,\r
-  performs a bitwise inclusive OR between the result of the AND operation and\r
+  performs a bitwise OR between the result of the AND operation and\r
   the value specified by OrData, and writes the result to the 16-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -609,7 +764,7 @@ PciCf8And16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
   @param  OrData  The value to OR with the result of the AND operation.\r
@@ -625,13 +780,22 @@ PciCf8AndThenOr16 (
   IN      UINT16                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAndThenOr16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoAndThenOr16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             AndData,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -648,7 +812,7 @@ PciCf8AndThenOr16 (
   If EndBit is greater than 15, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to read.\r
+  @param  Address   The PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..15.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -665,13 +829,22 @@ PciCf8BitFieldRead16 (
   IN      UINTN                     EndBit\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldRead16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           StartBit,\r
-           EndBit\r
-           );\r
+  Result = IoBitFieldRead16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             StartBit,\r
+             EndBit\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -688,13 +861,14 @@ PciCf8BitFieldRead16 (
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..15.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
                     Range 0..15.\r
-  @param  Value     New value of the bit field.\r
+  @param  Value     The new value of the bit field.\r
 \r
   @return The value written back to the PCI configuration register.\r
 \r
@@ -708,14 +882,23 @@ PciCf8BitFieldWrite16 (
   IN      UINT16                    Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldWrite16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           StartBit,\r
-           EndBit,\r
-           Value\r
-           );\r
+  Result = IoBitFieldWrite16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             StartBit,\r
+             EndBit,\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -723,7 +906,7 @@ PciCf8BitFieldWrite16 (
   writes the result back to the bit field in the 16-bit port.\r
 \r
   Reads the 16-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 16-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -735,8 +918,9 @@ PciCf8BitFieldWrite16 (
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..15.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -755,14 +939,23 @@ PciCf8BitFieldOr16 (
   IN      UINT16                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldOr16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           StartBit,\r
-           EndBit,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldOr16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             StartBit,\r
+             EndBit,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -782,8 +975,9 @@ PciCf8BitFieldOr16 (
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..15.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -802,23 +996,32 @@ PciCf8BitFieldAnd16 (
   IN      UINT16                    AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAnd16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           StartBit,\r
-           EndBit,\r
-           AndData\r
-           );\r
+  Result = IoBitFieldAnd16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             StartBit,\r
+             EndBit,\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
-  bitwise inclusive OR, and writes the result back to the bit field in the\r
+  bitwise OR, and writes the result back to the bit field in the\r
   16-bit port.\r
 \r
   Reads the 16-bit PCI configuration register specified by Address, performs a\r
-  bitwise AND followed by a bitwise inclusive OR between the read result and\r
+  bitwise AND followed by a bitwise OR between the read result and\r
   the value specified by AndData, and writes the result to the 16-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -831,8 +1034,10 @@ PciCf8BitFieldAnd16 (
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..15.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -853,15 +1058,24 @@ PciCf8BitFieldAndThenOr16(
   IN      UINT16                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT16   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAndThenOr16 (\r
-           PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
-           StartBit,\r
-           EndBit,\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldAndThenOr16 (\r
+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
+             StartBit,\r
+             EndBit,\r
+             AndData,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -875,7 +1089,7 @@ PciCf8BitFieldAndThenOr16(
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
 \r
   @return The read value from the PCI configuration register.\r
@@ -887,9 +1101,18 @@ PciCf8Read32 (
   IN      UINTN                     Address\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoRead32 (PCI_CONFIGURATION_DATA_PORT);\r
+  Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -903,7 +1126,7 @@ PciCf8Read32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  Value   The value to write.\r
 \r
@@ -917,20 +1140,29 @@ PciCf8Write32 (
   IN      UINT32                    Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoWrite32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           Value\r
-           );\r
+  Result = IoWrite32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
-  Performs a bitwise inclusive OR of a 32-bit PCI configuration register with\r
+  Performs a bitwise OR of a 32-bit PCI configuration register with\r
   a 32-bit value.\r
 \r
   Reads the 32-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 32-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -940,7 +1172,7 @@ PciCf8Write32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  OrData  The value to OR with the PCI configuration register.\r
 \r
@@ -954,12 +1186,21 @@ PciCf8Or32 (
   IN      UINT32                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoOr32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           OrData\r
-           );\r
+  Result = IoOr32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -977,7 +1218,7 @@ PciCf8Or32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
 \r
@@ -991,21 +1232,30 @@ PciCf8And32 (
   IN      UINT32                    AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAnd32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           AndData\r
-           );\r
+  Result = IoAnd32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
-  value, followed a  bitwise inclusive OR with another 32-bit value.\r
+  value, followed a  bitwise OR with another 32-bit value.\r
 \r
   Reads the 32-bit PCI configuration register specified by Address, performs a\r
   bitwise AND between the read result and the value specified by AndData,\r
-  performs a bitwise inclusive OR between the result of the AND operation and\r
+  performs a bitwise OR between the result of the AND operation and\r
   the value specified by OrData, and writes the result to the 32-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -1015,7 +1265,7 @@ PciCf8And32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If the register specified by Address >= 0x100, then ASSERT().\r
 \r
-  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+  @param  Address The address that encodes the PCI Bus, Device, Function and\r
                   Register.\r
   @param  AndData The value to AND with the PCI configuration register.\r
   @param  OrData  The value to OR with the result of the AND operation.\r
@@ -1031,13 +1281,22 @@ PciCf8AndThenOr32 (
   IN      UINT32                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoAndThenOr32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoAndThenOr32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             AndData,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -1054,7 +1313,7 @@ PciCf8AndThenOr32 (
   If EndBit is greater than 31, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to read.\r
+  @param  Address   The PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..31.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -1071,13 +1330,22 @@ PciCf8BitFieldRead32 (
   IN      UINTN                     EndBit\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldRead32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           StartBit,\r
-           EndBit\r
-           );\r
+  Result = IoBitFieldRead32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             StartBit,\r
+             EndBit\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -1094,13 +1362,14 @@ PciCf8BitFieldRead32 (
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..31.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
                     Range 0..31.\r
-  @param  Value     New value of the bit field.\r
+  @param  Value     The new value of the bit field.\r
 \r
   @return The value written back to the PCI configuration register.\r
 \r
@@ -1114,14 +1383,23 @@ PciCf8BitFieldWrite32 (
   IN      UINT32                    Value\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldWrite32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           StartBit,\r
-           EndBit,\r
-           Value\r
-           );\r
+  Result = IoBitFieldWrite32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             StartBit,\r
+             EndBit,\r
+             Value\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -1129,7 +1407,7 @@ PciCf8BitFieldWrite32 (
   writes the result back to the bit field in the 32-bit port.\r
 \r
   Reads the 32-bit PCI configuration register specified by Address, performs a\r
-  bitwise inclusive OR between the read result and the value specified by\r
+  bitwise OR between the read result and the value specified by\r
   OrData, and writes the result to the 32-bit PCI configuration register\r
   specified by Address. The value written to the PCI configuration register is\r
   returned. This function must guarantee that all PCI read and write operations\r
@@ -1141,8 +1419,9 @@ PciCf8BitFieldWrite32 (
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..31.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -1161,14 +1440,23 @@ PciCf8BitFieldOr32 (
   IN      UINT32                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldOr32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           StartBit,\r
-           EndBit,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldOr32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             StartBit,\r
+             EndBit,\r
+             OrData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -1188,8 +1476,9 @@ PciCf8BitFieldOr32 (
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..31.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -1208,23 +1497,32 @@ PciCf8BitFieldAnd32 (
   IN      UINT32                    AndData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAnd32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           StartBit,\r
-           EndBit,\r
-           AndData\r
-           );\r
+  Result = IoBitFieldAnd32 (\r
+             PCI_CONFIGURATION_DATA_PORT,\r
+             StartBit,\r
+             EndBit,\r
+             AndData\r
+             );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
   Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
-  bitwise inclusive OR, and writes the result back to the bit field in the\r
+  bitwise OR, and writes the result back to the bit field in the\r
   32-bit port.\r
 \r
   Reads the 32-bit PCI configuration register specified by Address, performs a\r
-  bitwise AND followed by a bitwise inclusive OR between the read result and\r
+  bitwise AND followed by a bitwise OR between the read result and\r
   the value specified by AndData, and writes the result to the 32-bit PCI\r
   configuration register specified by Address. The value written to the PCI\r
   configuration register is returned. This function must guarantee that all PCI\r
@@ -1237,8 +1535,10 @@ PciCf8BitFieldAnd32 (
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
   If EndBit is less than StartBit, then ASSERT().\r
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
 \r
-  @param  Address   PCI configuration register to write.\r
+  @param  Address   The PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
                     Range 0..31.\r
   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
@@ -1259,15 +1559,24 @@ PciCf8BitFieldAndThenOr32(
   IN      UINT32                    OrData\r
   )\r
 {\r
+  BOOLEAN  InterruptState;\r
+  UINT32   AddressPort;\r
+  UINT32   Result;\r
+\r
   ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
   IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
-  return IoBitFieldAndThenOr32 (\r
-           PCI_CONFIGURATION_DATA_PORT,\r
-           StartBit,\r
-           EndBit,\r
-           AndData,\r
-           OrData\r
-           );\r
+  Result = IoBitFieldAndThenOr32 (\r
+               PCI_CONFIGURATION_DATA_PORT,\r
+               StartBit,\r
+               EndBit,\r
+               AndData,\r
+               OrData\r
+               );\r
+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
+  SetInterruptState (InterruptState);\r
+  return Result;\r
 }\r
 \r
 /**\r
@@ -1286,12 +1595,12 @@ PciCf8BitFieldAndThenOr32(
   If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
   If Size > 0 and Buffer is NULL, then ASSERT().\r
 \r
-  @param  StartAddress  Starting address that encodes the PCI Bus, Device,\r
+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,\r
                         Function and Register.\r
-  @param  Size          Size in bytes of the transfer.\r
-  @param  Buffer        Pointer to a buffer receiving the data read.\r
+  @param  Size          The size in bytes of the transfer.\r
+  @param  Buffer        The pointer to a buffer receiving the data read.\r
 \r
-  @return Size\r
+  @return Size read from StartAddress.\r
 \r
 **/\r
 UINTN\r
@@ -1386,12 +1695,12 @@ PciCf8ReadBuffer (
   If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
   If Size > 0 and Buffer is NULL, then ASSERT().\r
 \r
-  @param  StartAddress  Starting address that encodes the PCI Bus, Device,\r
+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,\r
                         Function and Register.\r
-  @param  Size          Size in bytes of the transfer.\r
-  @param  Buffer        Pointer to a buffer containing the data to write.\r
+  @param  Size          The size in bytes of the transfer.\r
+  @param  Buffer        The pointer to a buffer containing the data to write.\r
 \r
-  @return Size\r
+  @return Size written to StartAddress.\r
 \r
 **/\r
 UINTN\r