]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/SmmPciExpressLib/PciExpressLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / SmmPciExpressLib / PciExpressLib.c
index f9fd3674d17ab80a8f52598a1ff7c54c8e360cd8..d7876a9fb3612e66f5da9542c7745efd29f1dab7 100644 (file)
@@ -7,13 +7,7 @@
 \r
  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.\r
  Portions copyright (c) 2016, American Megatrends, Inc. All rights reserved.\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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <Library/PcdLib.h>\r
 \r
 ///\r
-/// Module global that contains the base physical address of the PCI Express MMIO range.\r
+/// Module global that contains the base physical address and size of the PCI Express MMIO range.\r
 ///\r
-UINTN mSmmPciExpressLibPciExpressBaseAddress = 0;\r
+UINTN  mSmmPciExpressLibPciExpressBaseAddress = 0;\r
+UINTN  mSmmPciExpressLibPciExpressBaseSize    = 0;\r
 \r
 /**\r
  The constructor function caches the PCI Express Base Address\r
@@ -41,16 +36,17 @@ UINTN mSmmPciExpressLibPciExpressBaseAddress = 0;
 EFI_STATUS\r
 EFIAPI\r
 SmmPciExpressLibConstructor (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
 IN EFI_HANDLE        ImageHandle,\r
 IN EFI_SYSTEM_TABLE  *SystemTable\r
 )\r
 {\r
- //\r
- // Cache the physical address of the PCI Express MMIO range into a module global variable\r
- //\r
- mSmmPciExpressLibPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);\r
+  //\r
+  // Cache the physical address and size of the PCI Express MMIO range into a module global variable\r
+  //\r
+  mSmmPciExpressLibPciExpressBaseAddress = (UINTN)PcdGet64 (PcdPciExpressBaseAddress);\r
+  mSmmPciExpressLibPciExpressBaseSize    = (UINTN)PcdGet64 (PcdPciExpressBaseSize);\r
 \r
- return EFI_SUCCESS;\r
 return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -88,11 +84,11 @@ SmmPciExpressLibConstructor (
 RETURN_STATUS\r
 EFIAPI\r
 PciExpressRegisterForRuntimeAccess (\r
IN UINTN Address\r
- )\r
 IN UINTN  Address\r
 )\r
 {\r
- ASSERT_INVALID_PCI_ADDRESS (Address);\r
- return RETURN_UNSUPPORTED;\r
 ASSERT_INVALID_PCI_ADDRESS (Address);\r
 return RETURN_UNSUPPORTED;\r
 }\r
 \r
 /**\r
@@ -103,20 +99,31 @@ PciExpressRegisterForRuntimeAccess (
  mSmmPciExpressLibPciExpressBaseAddress is initialized in the library constructor from PCD entry\r
  PcdPciExpressBaseAddress.\r
 \r
+ If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
  @param Address The address that encodes the PCI Bus, Device, Function and Register.\r
- @return MMIO address corresponding to Address.\r
+\r
+ @retval (UINTN)-1 Invalid PCI address.\r
+ @retval other     MMIO address corresponding to Address.\r
 \r
 **/\r
 UINTN\r
 GetPciExpressAddress (\r
IN UINTN Address\r
- )\r
 IN UINTN  Address\r
 )\r
 {\r
- //\r
- // Make sure Address is valid\r
- //\r
- ASSERT_INVALID_PCI_ADDRESS (Address);\r
- return mSmmPciExpressLibPciExpressBaseAddress + Address;\r
+  //\r
+  // Make sure Address is valid\r
+  //\r
+  ASSERT_INVALID_PCI_ADDRESS (Address);\r
+  //\r
+  // Make sure the Address is in MMCONF address space\r
+  //\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINTN)-1;\r
+  }\r
+\r
+  return mSmmPciExpressLibPciExpressBaseAddress + Address;\r
 }\r
 \r
 /**\r
@@ -131,16 +138,21 @@ GetPciExpressAddress (
  @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
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The read value from the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressRead8 (\r
IN UINTN Address\r
- )\r
 IN UINTN  Address\r
 )\r
 {\r
- return MmioRead8 (GetPciExpressAddress (Address));\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioRead8 (GetPciExpressAddress (Address));\r
 }\r
 \r
 /**\r
@@ -156,17 +168,22 @@ PciExpressRead8 (
  Register.\r
  @param Value The value to write.\r
 \r
- @return The value written to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressWrite8 (\r
IN UINTN Address,\r
IN UINT8 Value\r
- )\r
 IN UINTN  Address,\r
 IN UINT8  Value\r
 )\r
 {\r
- return MmioWrite8 (GetPciExpressAddress (Address), Value);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioWrite8 (GetPciExpressAddress (Address), Value);\r
 }\r
 \r
 /**\r
@@ -186,17 +203,22 @@ PciExpressWrite8 (
  Register.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressOr8 (\r
IN UINTN Address,\r
IN UINT8 OrData\r
- )\r
 IN UINTN  Address,\r
 IN UINT8  OrData\r
 )\r
 {\r
- return MmioOr8 (GetPciExpressAddress (Address), OrData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioOr8 (GetPciExpressAddress (Address), OrData);\r
 }\r
 \r
 /**\r
@@ -216,17 +238,22 @@ PciExpressOr8 (
  Register.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressAnd8 (\r
IN UINTN Address,\r
IN UINT8 AndData\r
- )\r
 IN UINTN  Address,\r
 IN UINT8  AndData\r
 )\r
 {\r
- return MmioAnd8 (GetPciExpressAddress (Address), AndData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioAnd8 (GetPciExpressAddress (Address), AndData);\r
 }\r
 \r
 /**\r
@@ -248,22 +275,27 @@ PciExpressAnd8 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressAndThenOr8 (\r
IN UINTN Address,\r
IN UINT8 AndData,\r
IN UINT8 OrData\r
- )\r
 IN UINTN  Address,\r
 IN UINT8  AndData,\r
 IN UINT8  OrData\r
 )\r
 {\r
- return MmioAndThenOr8 (\r
- GetPciExpressAddress (Address),\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioAndThenOr8 (\r
+           GetPciExpressAddress (Address),\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -284,22 +316,27 @@ PciExpressAndThenOr8 (
  @param EndBit The ordinal of the most significant bit in the bit field.\r
  Range 0..7.\r
 \r
- @return The value of the bit field read from the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value of the bit field read from the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressBitFieldRead8 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit\r
 )\r
 {\r
- return MmioBitFieldRead8 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioBitFieldRead8 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit\r
+           );\r
 }\r
 \r
 /**\r
@@ -323,24 +360,29 @@ PciExpressBitFieldRead8 (
  Range 0..7.\r
  @param Value The new value of the bit field.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressBitFieldWrite8 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT8 Value\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit,\r
 IN UINT8  Value\r
 )\r
 {\r
- return MmioBitFieldWrite8 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- Value\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioBitFieldWrite8 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           Value\r
+           );\r
 }\r
 \r
 /**\r
@@ -367,24 +409,29 @@ PciExpressBitFieldWrite8 (
  Range 0..7.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressBitFieldOr8 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT8 OrData\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit,\r
 IN UINT8  OrData\r
 )\r
 {\r
- return MmioBitFieldOr8 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioBitFieldOr8 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -411,24 +458,29 @@ PciExpressBitFieldOr8 (
  Range 0..7.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressBitFieldAnd8 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT8 AndData\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit,\r
 IN UINT8  AndData\r
 )\r
 {\r
- return MmioBitFieldAnd8 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioBitFieldAnd8 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData\r
+           );\r
 }\r
 \r
 /**\r
@@ -459,26 +511,31 @@ PciExpressBitFieldAnd8 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT8\r
 EFIAPI\r
 PciExpressBitFieldAndThenOr8 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT8 AndData,\r
IN UINT8 OrData\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit,\r
 IN UINT8  AndData,\r
 IN UINT8  OrData\r
 )\r
 {\r
- return MmioBitFieldAndThenOr8 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT8)-1;\r
+  }\r
+\r
+  return MmioBitFieldAndThenOr8 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -494,16 +551,21 @@ PciExpressBitFieldAndThenOr8 (
  @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
+ @retval 0xFF  Invalid PCI address.\r
+ @retval other The read value from the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressRead16 (\r
IN UINTN Address\r
- )\r
 IN UINTN  Address\r
 )\r
 {\r
- return MmioRead16 (GetPciExpressAddress (Address));\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioRead16 (GetPciExpressAddress (Address));\r
 }\r
 \r
 /**\r
@@ -520,17 +582,22 @@ PciExpressRead16 (
  Register.\r
  @param Value The value to write.\r
 \r
- @return The value written to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressWrite16 (\r
IN UINTN Address,\r
IN UINT16 Value\r
- )\r
 IN UINTN   Address,\r
 IN UINT16  Value\r
 )\r
 {\r
- return MmioWrite16 (GetPciExpressAddress (Address), Value);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioWrite16 (GetPciExpressAddress (Address), Value);\r
 }\r
 \r
 /**\r
@@ -551,17 +618,22 @@ PciExpressWrite16 (
  Register.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressOr16 (\r
IN UINTN Address,\r
IN UINT16 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINT16  OrData\r
 )\r
 {\r
- return MmioOr16 (GetPciExpressAddress (Address), OrData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioOr16 (GetPciExpressAddress (Address), OrData);\r
 }\r
 \r
 /**\r
@@ -582,17 +654,22 @@ PciExpressOr16 (
  Register.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressAnd16 (\r
IN UINTN Address,\r
IN UINT16 AndData\r
- )\r
 IN UINTN   Address,\r
 IN UINT16  AndData\r
 )\r
 {\r
- return MmioAnd16 (GetPciExpressAddress (Address), AndData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioAnd16 (GetPciExpressAddress (Address), AndData);\r
 }\r
 \r
 /**\r
@@ -615,22 +692,27 @@ PciExpressAnd16 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressAndThenOr16 (\r
IN UINTN Address,\r
IN UINT16 AndData,\r
IN UINT16 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINT16  AndData,\r
 IN UINT16  OrData\r
 )\r
 {\r
- return MmioAndThenOr16 (\r
- GetPciExpressAddress (Address),\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioAndThenOr16 (\r
+           GetPciExpressAddress (Address),\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -652,22 +734,27 @@ PciExpressAndThenOr16 (
  @param EndBit The ordinal of the most significant bit in the bit field.\r
  Range 0..15.\r
 \r
- @return The value of the bit field read from the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value of the bit field read from the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressBitFieldRead16 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit\r
 )\r
 {\r
- return MmioBitFieldRead16 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioBitFieldRead16 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit\r
+           );\r
 }\r
 \r
 /**\r
@@ -692,24 +779,29 @@ PciExpressBitFieldRead16 (
  Range 0..15.\r
  @param Value The new value of the bit field.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressBitFieldWrite16 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT16 Value\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT16  Value\r
 )\r
 {\r
- return MmioBitFieldWrite16 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- Value\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioBitFieldWrite16 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           Value\r
+           );\r
 }\r
 \r
 /**\r
@@ -737,24 +829,29 @@ PciExpressBitFieldWrite16 (
  Range 0..15.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressBitFieldOr16 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT16 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT16  OrData\r
 )\r
 {\r
- return MmioBitFieldOr16 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioBitFieldOr16 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -782,24 +879,29 @@ PciExpressBitFieldOr16 (
  Range 0..15.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressBitFieldAnd16 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT16 AndData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT16  AndData\r
 )\r
 {\r
- return MmioBitFieldAnd16 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioBitFieldAnd16 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData\r
+           );\r
 }\r
 \r
 /**\r
@@ -831,26 +933,31 @@ PciExpressBitFieldAnd16 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFF  Invalid PCI address.\r
+ @retval other   The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT16\r
 EFIAPI\r
 PciExpressBitFieldAndThenOr16 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT16 AndData,\r
IN UINT16 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT16  AndData,\r
 IN UINT16  OrData\r
 )\r
 {\r
- return MmioBitFieldAndThenOr16 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT16)-1;\r
+  }\r
+\r
+  return MmioBitFieldAndThenOr16 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -866,16 +973,21 @@ PciExpressBitFieldAndThenOr16 (
  @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
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The read value from the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressRead32 (\r
IN UINTN Address\r
- )\r
 IN UINTN  Address\r
 )\r
 {\r
- return MmioRead32 (GetPciExpressAddress (Address));\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioRead32 (GetPciExpressAddress (Address));\r
 }\r
 \r
 /**\r
@@ -892,17 +1004,22 @@ PciExpressRead32 (
  Register.\r
  @param Value The value to write.\r
 \r
- @return The value written to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressWrite32 (\r
IN UINTN Address,\r
IN UINT32 Value\r
- )\r
 IN UINTN   Address,\r
 IN UINT32  Value\r
 )\r
 {\r
- return MmioWrite32 (GetPciExpressAddress (Address), Value);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioWrite32 (GetPciExpressAddress (Address), Value);\r
 }\r
 \r
 /**\r
@@ -923,17 +1040,22 @@ PciExpressWrite32 (
  Register.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressOr32 (\r
IN UINTN Address,\r
IN UINT32 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINT32  OrData\r
 )\r
 {\r
- return MmioOr32 (GetPciExpressAddress (Address), OrData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioOr32 (GetPciExpressAddress (Address), OrData);\r
 }\r
 \r
 /**\r
@@ -954,17 +1076,22 @@ PciExpressOr32 (
  Register.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressAnd32 (\r
IN UINTN Address,\r
IN UINT32 AndData\r
- )\r
 IN UINTN   Address,\r
 IN UINT32  AndData\r
 )\r
 {\r
- return MmioAnd32 (GetPciExpressAddress (Address), AndData);\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioAnd32 (GetPciExpressAddress (Address), AndData);\r
 }\r
 \r
 /**\r
@@ -987,22 +1114,27 @@ PciExpressAnd32 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressAndThenOr32 (\r
IN UINTN Address,\r
IN UINT32 AndData,\r
IN UINT32 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINT32  AndData,\r
 IN UINT32  OrData\r
 )\r
 {\r
- return MmioAndThenOr32 (\r
- GetPciExpressAddress (Address),\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioAndThenOr32 (\r
+           GetPciExpressAddress (Address),\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -1024,22 +1156,27 @@ PciExpressAndThenOr32 (
  @param EndBit The ordinal of the most significant bit in the bit field.\r
  Range 0..31.\r
 \r
- @return The value of the bit field read from the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value of the bit field read from the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressBitFieldRead32 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit\r
- )\r
 IN UINTN  Address,\r
 IN UINTN  StartBit,\r
 IN UINTN  EndBit\r
 )\r
 {\r
- return MmioBitFieldRead32 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioBitFieldRead32 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit\r
+           );\r
 }\r
 \r
 /**\r
@@ -1064,24 +1201,29 @@ PciExpressBitFieldRead32 (
  Range 0..31.\r
  @param Value The new value of the bit field.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressBitFieldWrite32 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT32 Value\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT32  Value\r
 )\r
 {\r
- return MmioBitFieldWrite32 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- Value\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioBitFieldWrite32 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           Value\r
+           );\r
 }\r
 \r
 /**\r
@@ -1109,24 +1251,29 @@ PciExpressBitFieldWrite32 (
  Range 0..31.\r
  @param OrData The value to OR with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressBitFieldOr32 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT32 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT32  OrData\r
 )\r
 {\r
- return MmioBitFieldOr32 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioBitFieldOr32 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -1154,24 +1301,29 @@ PciExpressBitFieldOr32 (
  Range 0..31.\r
  @param AndData The value to AND with the PCI configuration register.\r
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressBitFieldAnd32 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT32 AndData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT32  AndData\r
 )\r
 {\r
- return MmioBitFieldAnd32 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioBitFieldAnd32 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData\r
+           );\r
 }\r
 \r
 /**\r
@@ -1203,26 +1355,31 @@ PciExpressBitFieldAnd32 (
  @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
 \r
- @return The value written back to the PCI configuration register.\r
+ @retval 0xFFFFFFFF Invalid PCI address.\r
+ @retval other      The value written back to the PCI configuration register.\r
 \r
 **/\r
 UINT32\r
 EFIAPI\r
 PciExpressBitFieldAndThenOr32 (\r
IN UINTN Address,\r
IN UINTN StartBit,\r
IN UINTN EndBit,\r
IN UINT32 AndData,\r
IN UINT32 OrData\r
- )\r
 IN UINTN   Address,\r
 IN UINTN   StartBit,\r
 IN UINTN   EndBit,\r
 IN UINT32  AndData,\r
 IN UINT32  OrData\r
 )\r
 {\r
- return MmioBitFieldAndThenOr32 (\r
- GetPciExpressAddress (Address),\r
- StartBit,\r
- EndBit,\r
- AndData,\r
- OrData\r
- );\r
+  if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINT32)-1;\r
+  }\r
+\r
+  return MmioBitFieldAndThenOr32 (\r
+           GetPciExpressAddress (Address),\r
+           StartBit,\r
+           EndBit,\r
+           AndData,\r
+           OrData\r
+           );\r
 }\r
 \r
 /**\r
@@ -1232,7 +1389,7 @@ PciExpressBitFieldAndThenOr32 (
  Size into the buffer specified by Buffer. This function only allows the PCI\r
  configuration registers from a single PCI function to be read. Size is\r
  returned. When possible 32-bit PCI configuration read cycles are used to read\r
- from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
+ from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
  and 16-bit PCI configuration read cycles may be used at the beginning and the\r
  end of the range.\r
 \r
@@ -1245,86 +1402,94 @@ PciExpressBitFieldAndThenOr32 (
  @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 data from StartAddress.\r
+ @retval (UINTN)-1 Invalid PCI address.\r
+ @retval other     Size read data from StartAddress.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 PciExpressReadBuffer (\r
IN UINTN StartAddress,\r
IN UINTN Size,\r
OUT VOID *Buffer\r
- )\r
 IN UINTN  StartAddress,\r
 IN UINTN  Size,\r
 OUT VOID  *Buffer\r
 )\r
 {\r
- UINTN ReturnValue;\r
-\r
- //\r
- // Make sure Address is valid\r
- //\r
- ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
- ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
-\r
- if (Size == 0) {\r
- return Size;\r
- }\r
-\r
- ASSERT (Buffer != NULL);\r
-\r
- //\r
- // Save Size for return\r
- //\r
- ReturnValue = Size;\r
-\r
- if ((StartAddress & 1) != 0) {\r
- //\r
- // Read a byte if StartAddress is byte aligned\r
- //\r
- *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
- StartAddress += sizeof (UINT8);\r
- Size -= sizeof (UINT8);\r
- Buffer = (UINT8*)Buffer + 1;\r
- }\r
-\r
- if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
- //\r
- // Read a word if StartAddress is word aligned\r
- //\r
- WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));\r
-\r
- StartAddress += sizeof (UINT16);\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) PciExpressRead32 (StartAddress));\r
-\r
- StartAddress += sizeof (UINT32);\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) PciExpressRead16 (StartAddress));\r
- StartAddress += sizeof (UINT16);\r
- Size -= sizeof (UINT16);\r
- Buffer = (UINT16*)Buffer + 1;\r
- }\r
-\r
- if (Size >= sizeof (UINT8)) {\r
- //\r
- // Read the last remaining byte if exist\r
- //\r
- *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
- }\r
-\r
- return ReturnValue;\r
+  UINTN  ReturnValue;\r
+\r
+  //\r
+  // Make sure Address is valid\r
+  //\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
+\r
+  //\r
+  // Make sure the Address is in MMCONF address space\r
+  //\r
+  if (StartAddress >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINTN)-1;\r
+  }\r
+\r
+  if (Size == 0) {\r
+    return Size;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Read a byte if StartAddress is byte aligned\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
+    StartAddress             += sizeof (UINT8);\r
+    Size                     -= sizeof (UINT8);\r
+    Buffer                    = (UINT8 *)Buffer + 1;\r
+  }\r
+\r
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
+    //\r
+    // Read a word if StartAddress is word aligned\r
+    //\r
+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));\r
+\r
+    StartAddress += sizeof (UINT16);\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)PciExpressRead32 (StartAddress));\r
+\r
+    StartAddress += sizeof (UINT32);\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)PciExpressRead16 (StartAddress));\r
+    StartAddress += sizeof (UINT16);\r
+    Size         -= sizeof (UINT16);\r
+    Buffer        = (UINT16 *)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT8)) {\r
+    //\r
+    // Read the last remaining byte if exist\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
+  }\r
+\r
+  return ReturnValue;\r
 }\r
 \r
 /**\r
@@ -1335,7 +1500,7 @@ PciExpressReadBuffer (
  Size from the buffer specified by Buffer. This function only allows the PCI\r
  configuration registers from a single PCI function to be written. Size is\r
  returned. When possible 32-bit PCI configuration write cycles are used to\r
- write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
+ write from StartAddress to StartAddress + Size. Due to alignment restrictions,\r
  8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
  and the end of the range.\r
 \r
@@ -1348,83 +1513,90 @@ PciExpressReadBuffer (
  @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
+ @retval (UINTN)-1 Invalid PCI address.\r
+ @retval other     Size written to StartAddress.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 PciExpressWriteBuffer (\r
IN UINTN StartAddress,\r
IN UINTN Size,\r
IN VOID *Buffer\r
- )\r
 IN UINTN  StartAddress,\r
 IN UINTN  Size,\r
 IN VOID   *Buffer\r
 )\r
 {\r
- UINTN ReturnValue;\r
-\r
- //\r
- // Make sure Address is valid\r
- //\r
- ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
- ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
-\r
-\r
- if (Size == 0) {\r
- return 0;\r
- }\r
-\r
- ASSERT (Buffer != NULL);\r
-\r
- //\r
- // Save Size for return\r
- //\r
- ReturnValue = Size;\r
-\r
- if ((StartAddress & 1) != 0) {\r
- //\r
- // Write a byte if StartAddress is byte aligned\r
- //\r
- PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);\r
- StartAddress += sizeof (UINT8);\r
- Size -= sizeof (UINT8);\r
- Buffer = (UINT8*)Buffer + 1;\r
- }\r
-\r
- if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
- //\r
- // Write a word if StartAddress is word aligned\r
- //\r
- PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
- StartAddress += sizeof (UINT16);\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
- PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));\r
- StartAddress += sizeof (UINT32);\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
- PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
- StartAddress += sizeof (UINT16);\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
- PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);\r
- }\r
-\r
- return ReturnValue;\r
+  UINTN  ReturnValue;\r
+\r
+  //\r
+  // Make sure Address is valid\r
+  //\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
+\r
+  //\r
+  // Make sure the Address is in MMCONF address space\r
+  //\r
+  if (StartAddress >= mSmmPciExpressLibPciExpressBaseSize) {\r
+    return (UINTN)-1;\r
+  }\r
+\r
+  if (Size == 0) {\r
+    return 0;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Write a byte if StartAddress is byte aligned\r
+    //\r
+    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);\r
+    StartAddress += sizeof (UINT8);\r
+    Size         -= sizeof (UINT8);\r
+    Buffer        = (UINT8 *)Buffer + 1;\r
+  }\r
+\r
+  if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
+    //\r
+    // Write a word if StartAddress is word aligned\r
+    //\r
+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
+    StartAddress += sizeof (UINT16);\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
+    PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer));\r
+    StartAddress += sizeof (UINT32);\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
+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
+    StartAddress += sizeof (UINT16);\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
+    PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);\r
+  }\r
+\r
+  return ReturnValue;\r
 }\r