]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BasePciCf8Lib / PciCf8Lib.c
index cad60e7f0f0bb2f82028176807f7a7a889bfef82..0d9667178f834d3e836b9dbc81de1bd19ed9da83 100644 (file)
@@ -2,18 +2,11 @@
   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 - 2009, Intel Corporation. All rights reserved.<BR>\r
-  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
-\r
 #include <Base.h>\r
 \r
 #include <Library/BaseLib.h>\r
   @param  M Additional bits to assert to be zero.\r
 \r
 **/\r
-#define ASSERT_INVALID_PCI_ADDRESS(A,M) \\r
+#define ASSERT_INVALID_PCI_ADDRESS(A, M) \\r
   ASSERT (((A) & (~0xffff0ff | (M))) == 0)\r
 \r
 /**\r
-  Registers a PCI device so PCI configuration registers may be accessed after \r
+  Registers a PCI device so PCI configuration registers may be accessed after\r
   SetVirtualAddressMap().\r
-  \r
-  Registers the PCI device specified by Address so all the PCI configuration registers \r
+\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
+\r
   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
+\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
+  @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
@@ -102,7 +95,7 @@ PciCf8RegisterForRuntimeAccess (
   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
@@ -111,12 +104,21 @@ PciCf8RegisterForRuntimeAccess (
 UINT8\r
 EFIAPI\r
 PciCf8Read8 (\r
-  IN      UINTN                     Address\r
+  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
@@ -129,7 +131,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
@@ -139,16 +141,25 @@ PciCf8Read8 (
 UINT8\r
 EFIAPI\r
 PciCf8Write8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     Value\r
+  IN      UINTN  Address,\r
+  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
@@ -165,7 +176,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
@@ -175,16 +186,25 @@ PciCf8Write8 (
 UINT8\r
 EFIAPI\r
 PciCf8Or8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     OrData\r
+  IN      UINTN  Address,\r
+  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
@@ -201,7 +221,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
@@ -211,16 +231,25 @@ PciCf8Or8 (
 UINT8\r
 EFIAPI\r
 PciCf8And8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     AndData\r
+  IN      UINTN  Address,\r
+  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
@@ -238,7 +267,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
@@ -249,18 +278,27 @@ PciCf8And8 (
 UINT8\r
 EFIAPI\r
 PciCf8AndThenOr8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     AndData,\r
-  IN      UINT8                     OrData\r
+  IN      UINTN  Address,\r
+  IN      UINT8  AndData,\r
+  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
@@ -276,7 +314,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
@@ -288,18 +326,27 @@ PciCf8AndThenOr8 (
 UINT8\r
 EFIAPI\r
 PciCf8BitFieldRead8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  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
@@ -315,13 +362,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
@@ -329,20 +377,29 @@ PciCf8BitFieldRead8 (
 UINT8\r
 EFIAPI\r
 PciCf8BitFieldWrite8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT8                     Value\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  IN      UINTN  EndBit,\r
+  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
@@ -361,8 +418,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
@@ -375,20 +433,29 @@ PciCf8BitFieldWrite8 (
 UINT8\r
 EFIAPI\r
 PciCf8BitFieldOr8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT8                     OrData\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  IN      UINTN  EndBit,\r
+  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
@@ -407,8 +474,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
@@ -421,20 +489,29 @@ PciCf8BitFieldOr8 (
 UINT8\r
 EFIAPI\r
 PciCf8BitFieldAnd8 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT8                     AndData\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  IN      UINTN  EndBit,\r
+  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
@@ -455,8 +532,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
@@ -469,23 +548,32 @@ PciCf8BitFieldAnd8 (
 **/\r
 UINT8\r
 EFIAPI\r
-PciCf8BitFieldAndThenOr8(\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT8                     AndData,\r
-  IN      UINT8                     OrData\r
+PciCf8BitFieldAndThenOr8 (\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  IN      UINTN  EndBit,\r
+  IN      UINT8  AndData,\r
+  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
@@ -499,7 +587,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
@@ -508,12 +596,21 @@ PciCf8BitFieldAndThenOr8(
 UINT16\r
 EFIAPI\r
 PciCf8Read16 (\r
-  IN      UINTN                     Address\r
+  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
@@ -527,7 +624,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
@@ -537,16 +634,25 @@ PciCf8Read16 (
 UINT16\r
 EFIAPI\r
 PciCf8Write16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT16                    Value\r
+  IN      UINTN   Address,\r
+  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
@@ -564,7 +670,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
@@ -574,16 +680,25 @@ PciCf8Write16 (
 UINT16\r
 EFIAPI\r
 PciCf8Or16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT16                    OrData\r
+  IN      UINTN   Address,\r
+  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
@@ -601,7 +716,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
@@ -611,16 +726,25 @@ PciCf8Or16 (
 UINT16\r
 EFIAPI\r
 PciCf8And16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT16                    AndData\r
+  IN      UINTN   Address,\r
+  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
@@ -639,7 +763,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
@@ -650,18 +774,27 @@ PciCf8And16 (
 UINT16\r
 EFIAPI\r
 PciCf8AndThenOr16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT16                    AndData,\r
-  IN      UINT16                    OrData\r
+  IN      UINTN   Address,\r
+  IN      UINT16  AndData,\r
+  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
@@ -678,7 +811,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
@@ -690,18 +823,27 @@ PciCf8AndThenOr16 (
 UINT16\r
 EFIAPI\r
 PciCf8BitFieldRead16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  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
@@ -718,13 +860,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
@@ -732,20 +875,29 @@ PciCf8BitFieldRead16 (
 UINT16\r
 EFIAPI\r
 PciCf8BitFieldWrite16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT16                    Value\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -765,8 +917,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
@@ -779,20 +932,29 @@ PciCf8BitFieldWrite16 (
 UINT16\r
 EFIAPI\r
 PciCf8BitFieldOr16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT16                    OrData\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -812,8 +974,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
@@ -826,20 +989,29 @@ PciCf8BitFieldOr16 (
 UINT16\r
 EFIAPI\r
 PciCf8BitFieldAnd16 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT16                    AndData\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -861,8 +1033,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
@@ -875,23 +1049,32 @@ PciCf8BitFieldAnd16 (
 **/\r
 UINT16\r
 EFIAPI\r
-PciCf8BitFieldAndThenOr16(\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT16                    AndData,\r
-  IN      UINT16                    OrData\r
+PciCf8BitFieldAndThenOr16 (\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  IN      UINT16  AndData,\r
+  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
@@ -905,7 +1088,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
@@ -914,12 +1097,21 @@ PciCf8BitFieldAndThenOr16(
 UINT32\r
 EFIAPI\r
 PciCf8Read32 (\r
-  IN      UINTN                     Address\r
+  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
@@ -933,7 +1125,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
@@ -943,16 +1135,25 @@ PciCf8Read32 (
 UINT32\r
 EFIAPI\r
 PciCf8Write32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT32                    Value\r
+  IN      UINTN   Address,\r
+  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
@@ -970,7 +1171,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
@@ -980,16 +1181,25 @@ PciCf8Write32 (
 UINT32\r
 EFIAPI\r
 PciCf8Or32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT32                    OrData\r
+  IN      UINTN   Address,\r
+  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
@@ -1007,7 +1217,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
@@ -1017,16 +1227,25 @@ PciCf8Or32 (
 UINT32\r
 EFIAPI\r
 PciCf8And32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT32                    AndData\r
+  IN      UINTN   Address,\r
+  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
@@ -1045,7 +1264,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
@@ -1056,18 +1275,27 @@ PciCf8And32 (
 UINT32\r
 EFIAPI\r
 PciCf8AndThenOr32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINT32                    AndData,\r
-  IN      UINT32                    OrData\r
+  IN      UINTN   Address,\r
+  IN      UINT32  AndData,\r
+  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
@@ -1084,7 +1312,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
@@ -1096,18 +1324,27 @@ PciCf8AndThenOr32 (
 UINT32\r
 EFIAPI\r
 PciCf8BitFieldRead32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit\r
+  IN      UINTN  Address,\r
+  IN      UINTN  StartBit,\r
+  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
@@ -1124,13 +1361,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
@@ -1138,20 +1376,29 @@ PciCf8BitFieldRead32 (
 UINT32\r
 EFIAPI\r
 PciCf8BitFieldWrite32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT32                    Value\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -1171,8 +1418,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
@@ -1185,20 +1433,29 @@ PciCf8BitFieldWrite32 (
 UINT32\r
 EFIAPI\r
 PciCf8BitFieldOr32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT32                    OrData\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -1218,8 +1475,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
@@ -1232,20 +1490,29 @@ PciCf8BitFieldOr32 (
 UINT32\r
 EFIAPI\r
 PciCf8BitFieldAnd32 (\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT32                    AndData\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  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
@@ -1267,8 +1534,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
@@ -1281,23 +1550,32 @@ PciCf8BitFieldAnd32 (
 **/\r
 UINT32\r
 EFIAPI\r
-PciCf8BitFieldAndThenOr32(\r
-  IN      UINTN                     Address,\r
-  IN      UINTN                     StartBit,\r
-  IN      UINTN                     EndBit,\r
-  IN      UINT32                    AndData,\r
-  IN      UINT32                    OrData\r
+PciCf8BitFieldAndThenOr32 (\r
+  IN      UINTN   Address,\r
+  IN      UINTN   StartBit,\r
+  IN      UINTN   EndBit,\r
+  IN      UINT32  AndData,\r
+  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
@@ -1316,10 +1594,10 @@ 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 read from StartAddress.\r
 \r
@@ -1327,12 +1605,12 @@ PciCf8BitFieldAndThenOr32(
 UINTN\r
 EFIAPI\r
 PciCf8ReadBuffer (\r
-  IN      UINTN                     StartAddress,\r
-  IN      UINTN                     Size,\r
-  OUT     VOID                      *Buffer\r
+  IN      UINTN  StartAddress,\r
+  IN      UINTN  Size,\r
+  OUT     VOID   *Buffer\r
   )\r
 {\r
-  UINTN   ReturnValue;\r
+  UINTN  ReturnValue;\r
 \r
   ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
   ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
@@ -1353,40 +1631,40 @@ PciCf8ReadBuffer (
     // Read a byte if StartAddress is byte aligned\r
     //\r
     *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
-    StartAddress += sizeof (UINT8);\r
-    Size -= sizeof (UINT8);\r
-    Buffer = (UINT8*)Buffer + 1;\r
+    StartAddress             += sizeof (UINT8);\r
+    Size                     -= sizeof (UINT8);\r
+    Buffer                    = (UINT8 *)Buffer + 1;\r
   }\r
 \r
-  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
     //\r
     // Read a word if StartAddress is word aligned\r
     //\r
-    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciCf8Read16 (StartAddress));\r
 \r
     StartAddress += sizeof (UINT16);\r
-    Size -= sizeof (UINT16);\r
-    Buffer = (UINT16*)Buffer + 1;\r
+    Size         -= sizeof (UINT16);\r
+    Buffer        = (UINT16 *)Buffer + 1;\r
   }\r
 \r
   while (Size >= sizeof (UINT32)) {\r
     //\r
     // Read as many double words as possible\r
     //\r
-    WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));\r
+    WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)PciCf8Read32 (StartAddress));\r
     StartAddress += sizeof (UINT32);\r
-    Size -= sizeof (UINT32);\r
-    Buffer = (UINT32*)Buffer + 1;\r
+    Size         -= sizeof (UINT32);\r
+    Buffer        = (UINT32 *)Buffer + 1;\r
   }\r
 \r
   if (Size >= sizeof (UINT16)) {\r
     //\r
     // Read the last remaining word if exist\r
     //\r
-    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciCf8Read16 (StartAddress));\r
     StartAddress += sizeof (UINT16);\r
-    Size -= sizeof (UINT16);\r
-    Buffer = (UINT16*)Buffer + 1;\r
+    Size         -= sizeof (UINT16);\r
+    Buffer        = (UINT16 *)Buffer + 1;\r
   }\r
 \r
   if (Size >= sizeof (UINT8)) {\r
@@ -1416,10 +1694,10 @@ 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 written to StartAddress.\r
 \r
@@ -1427,12 +1705,12 @@ PciCf8ReadBuffer (
 UINTN\r
 EFIAPI\r
 PciCf8WriteBuffer (\r
-  IN      UINTN                     StartAddress,\r
-  IN      UINTN                     Size,\r
-  IN      VOID                      *Buffer\r
+  IN      UINTN  StartAddress,\r
+  IN      UINTN  Size,\r
+  IN      VOID   *Buffer\r
   )\r
 {\r
-  UINTN   ReturnValue;\r
+  UINTN  ReturnValue;\r
 \r
   ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
   ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
@@ -1452,47 +1730,47 @@ PciCf8WriteBuffer (
     //\r
     // Write a byte if StartAddress is byte aligned\r
     //\r
-    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
+    PciCf8Write8 (StartAddress, *(UINT8 *)Buffer);\r
     StartAddress += sizeof (UINT8);\r
-    Size -= sizeof (UINT8);\r
-    Buffer = (UINT8*)Buffer + 1;\r
+    Size         -= sizeof (UINT8);\r
+    Buffer        = (UINT8 *)Buffer + 1;\r
   }\r
 \r
-  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
     //\r
     // Write a word if StartAddress is word aligned\r
     //\r
-    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
+    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
     StartAddress += sizeof (UINT16);\r
-    Size -= sizeof (UINT16);\r
-    Buffer = (UINT16*)Buffer + 1;\r
+    Size         -= sizeof (UINT16);\r
+    Buffer        = (UINT16 *)Buffer + 1;\r
   }\r
 \r
   while (Size >= sizeof (UINT32)) {\r
     //\r
     // Write as many double words as possible\r
     //\r
-    PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));\r
+    PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer));\r
     StartAddress += sizeof (UINT32);\r
-    Size -= sizeof (UINT32);\r
-    Buffer = (UINT32*)Buffer + 1;\r
+    Size         -= sizeof (UINT32);\r
+    Buffer        = (UINT32 *)Buffer + 1;\r
   }\r
 \r
   if (Size >= sizeof (UINT16)) {\r
     //\r
     // Write the last remaining word if exist\r
     //\r
-    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
+    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
     StartAddress += sizeof (UINT16);\r
-    Size -= sizeof (UINT16);\r
-    Buffer = (UINT16*)Buffer + 1;\r
+    Size         -= sizeof (UINT16);\r
+    Buffer        = (UINT16 *)Buffer + 1;\r
   }\r
 \r
   if (Size >= sizeof (UINT8)) {\r
     //\r
     // Write the last remaining byte if exist\r
     //\r
-    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
+    PciCf8Write8 (StartAddress, *(UINT8 *)Buffer);\r
   }\r
 \r
   return ReturnValue;\r