]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePciExpressLib/PciLib.c
Checked in part of MDE library instances following PI and UEFI. It includes:
[mirror_edk2.git] / MdePkg / Library / BasePciExpressLib / PciLib.c
index a3dab38ec34f43a969d769325afc3d07fda201b6..30536dfbf6aa44fd54254b4a5de96a2fc3b2b5ad 100644 (file)
 \r
 **/\r
 \r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Base.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/PciExpressLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+\r
 /**\r
   Assert the validity of a PCI address. A valid PCI address should contain 1's\r
   only in the low 28 bits.\r
   ASSERT (((A) & ~0xfffffff) == 0)\r
 \r
 \r
-UINTN\r
-EFIAPI\r
+/**\r
+  Gets the base address of PCI Express.\r
+  \r
+  This internal functions retrieves PCI Express Base Address via a PCD entry\r
+  PcdPciExpressBaseAddress.\r
+  \r
+  @return The base address of PCI Express.\r
+\r
+**/\r
+STATIC\r
+volatile VOID*\r
 GetPciExpressBaseAddress (\r
   VOID\r
   )\r
 {\r
-  /// @bug Change this to a PCD Get call to retrieve the PCI-E Base Address\r
-  return 0xc0000000;\r
+  return (VOID*)(UINTN) PcdGet64 (PcdPciExpressBaseAddress);\r
 }\r
 \r
 /**\r
@@ -63,7 +87,7 @@ PciExpressRead8 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioRead8 (GetPciExpressBaseAddress () + Address);\r
+  return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address);\r
 }\r
 \r
 /**\r
@@ -90,7 +114,7 @@ PciExpressWrite8 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioWrite8 (GetPciExpressBaseAddress () + Address, Value);\r
+  return MmioWrite8 ((UINTN) GetPciExpressBaseAddress () + Address, Value);\r
 }\r
 \r
 /**\r
@@ -121,7 +145,7 @@ PciExpressOr8 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioOr8 (GetPciExpressBaseAddress () + Address, OrData);\r
+  return MmioOr8 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);\r
 }\r
 \r
 /**\r
@@ -152,7 +176,7 @@ PciExpressAnd8 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioAnd8 (GetPciExpressBaseAddress () + Address, AndData);\r
+  return MmioAnd8 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);\r
 }\r
 \r
 /**\r
@@ -187,7 +211,7 @@ PciExpressAndThenOr8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioAndThenOr8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            AndData,\r
            OrData\r
            );\r
@@ -203,7 +227,7 @@ PciExpressAndThenOr8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -224,7 +248,7 @@ PciExpressBitFieldRead8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldRead8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit\r
            );\r
@@ -241,7 +265,7 @@ PciExpressBitFieldRead8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -264,7 +288,7 @@ PciExpressBitFieldWrite8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldWrite8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            Value\r
@@ -285,7 +309,7 @@ PciExpressBitFieldWrite8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -308,7 +332,7 @@ PciExpressBitFieldOr8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldOr8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            OrData\r
@@ -329,7 +353,7 @@ PciExpressBitFieldOr8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -352,7 +376,7 @@ PciExpressBitFieldAnd8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAnd8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData\r
@@ -375,7 +399,7 @@ PciExpressBitFieldAnd8 (
   If Address > 0x0FFFFFFF, then ASSERT().\r
   If StartBit is greater than 7, then ASSERT().\r
   If EndBit is greater than 7, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -400,7 +424,7 @@ PciExpressBitFieldAndThenOr8 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAndThenOr8 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData,\r
@@ -431,7 +455,7 @@ PciExpressRead16 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioRead16 (GetPciExpressBaseAddress () + Address);\r
+  return MmioRead16 ((UINTN) GetPciExpressBaseAddress () + Address);\r
 }\r
 \r
 /**\r
@@ -459,7 +483,7 @@ PciExpressWrite16 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioWrite16 (GetPciExpressBaseAddress () + Address, Value);\r
+  return MmioWrite16 ((UINTN) GetPciExpressBaseAddress () + Address, Value);\r
 }\r
 \r
 /**\r
@@ -491,7 +515,7 @@ PciExpressOr16 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioOr16 (GetPciExpressBaseAddress () + Address, OrData);\r
+  return MmioOr16 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);\r
 }\r
 \r
 /**\r
@@ -523,7 +547,7 @@ PciExpressAnd16 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioAnd16 (GetPciExpressBaseAddress () + Address, AndData);\r
+  return MmioAnd16 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);\r
 }\r
 \r
 /**\r
@@ -559,7 +583,7 @@ PciExpressAndThenOr16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioAndThenOr16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            AndData,\r
            OrData\r
            );\r
@@ -576,7 +600,7 @@ PciExpressAndThenOr16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -597,7 +621,7 @@ PciExpressBitFieldRead16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldRead16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit\r
            );\r
@@ -615,7 +639,7 @@ PciExpressBitFieldRead16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -638,7 +662,7 @@ PciExpressBitFieldWrite16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldWrite16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            Value\r
@@ -660,7 +684,7 @@ PciExpressBitFieldWrite16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -683,7 +707,7 @@ PciExpressBitFieldOr16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldOr16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            OrData\r
@@ -705,7 +729,7 @@ PciExpressBitFieldOr16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -728,7 +752,7 @@ PciExpressBitFieldAnd16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAnd16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData\r
@@ -752,7 +776,7 @@ PciExpressBitFieldAnd16 (
   If Address is not aligned on a 16-bit boundary, then ASSERT().\r
   If StartBit is greater than 15, then ASSERT().\r
   If EndBit is greater than 15, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -777,7 +801,7 @@ PciExpressBitFieldAndThenOr16 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAndThenOr16 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData,\r
@@ -808,7 +832,7 @@ PciExpressRead32 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioRead32 (GetPciExpressBaseAddress () + Address);\r
+  return MmioRead32 ((UINTN) GetPciExpressBaseAddress () + Address);\r
 }\r
 \r
 /**\r
@@ -836,7 +860,7 @@ PciExpressWrite32 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioWrite32 (GetPciExpressBaseAddress () + Address, Value);\r
+  return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, Value);\r
 }\r
 \r
 /**\r
@@ -868,7 +892,7 @@ PciExpressOr32 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioOr32 (GetPciExpressBaseAddress () + Address, OrData);\r
+  return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);\r
 }\r
 \r
 /**\r
@@ -900,7 +924,7 @@ PciExpressAnd32 (
   )\r
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
-  return MmioAnd32 (GetPciExpressBaseAddress () + Address, AndData);\r
+  return MmioAnd32 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);\r
 }\r
 \r
 /**\r
@@ -936,7 +960,7 @@ PciExpressAndThenOr32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioAndThenOr32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            AndData,\r
            OrData\r
            );\r
@@ -953,7 +977,7 @@ PciExpressAndThenOr32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to read.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -974,7 +998,7 @@ PciExpressBitFieldRead32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldRead32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit\r
            );\r
@@ -992,7 +1016,7 @@ PciExpressBitFieldRead32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -1015,7 +1039,7 @@ PciExpressBitFieldWrite32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldWrite32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            Value\r
@@ -1037,7 +1061,7 @@ PciExpressBitFieldWrite32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -1060,7 +1084,7 @@ PciExpressBitFieldOr32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldOr32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            OrData\r
@@ -1082,7 +1106,7 @@ PciExpressBitFieldOr32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -1105,7 +1129,7 @@ PciExpressBitFieldAnd32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAnd32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData\r
@@ -1129,7 +1153,7 @@ PciExpressBitFieldAnd32 (
   If Address is not aligned on a 32-bit boundary, then ASSERT().\r
   If StartBit is greater than 31, then ASSERT().\r
   If EndBit is greater than 31, then ASSERT().\r
-  If EndBit is less than or equal to StartBit, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
 \r
   @param  Address   PCI configuration register to write.\r
   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
@@ -1154,7 +1178,7 @@ PciExpressBitFieldAndThenOr32 (
 {\r
   ASSERT_INVALID_PCI_ADDRESS (Address);\r
   return MmioBitFieldAndThenOr32 (\r
-           GetPciExpressBaseAddress () + Address,\r
+           (UINTN) GetPciExpressBaseAddress () + Address,\r
            StartBit,\r
            EndBit,\r
            AndData,\r
@@ -1175,8 +1199,7 @@ PciExpressBitFieldAndThenOr32 (
 \r
   If StartAddress > 0x0FFFFFFF, then ASSERT().\r
   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
-  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().\r
-  If Buffer is NULL, 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
                         Function and Register.\r
@@ -1194,54 +1217,70 @@ PciExpressReadBuffer (
   OUT     VOID                      *Buffer\r
   )\r
 {\r
-  UINTN                             EndAddress;\r
+  UINTN                             ReturnValue;\r
 \r
-  EndAddress = StartAddress + Size;\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
 \r
-  if (StartAddress < EndAddress && (StartAddress & 1)) {\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
-    *(UINT8*)Buffer = PciExpressRead8 (StartAddress);\r
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
     StartAddress += sizeof (UINT8);\r
+    Size -= sizeof (UINT8);\r
     Buffer = (UINT8*)Buffer + 1;\r
   }\r
 \r
-  if (StartAddress < EndAddress && (StartAddress & 2)) {\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
     //\r
     // Read a word if StartAddress is word aligned\r
     //\r
-    *(UINT16*)Buffer = PciExpressRead16 (StartAddress);\r
+    *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress);\r
     StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
     Buffer = (UINT16*)Buffer + 1;\r
   }\r
 \r
-  while (EndAddress - StartAddress >= 4) {\r
+  while (Size >= sizeof (UINT32)) {\r
     //\r
     // Read as many double words as possible\r
     //\r
-    *(UINT32*)Buffer = PciExpressRead32 (StartAddress);\r
+    *(volatile UINT32 *)Buffer = PciExpressRead32 (StartAddress);\r
     StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
     Buffer = (UINT32*)Buffer + 1;\r
   }\r
 \r
-  if ((EndAddress & 2) != 0) {\r
+  if (Size >= sizeof (UINT16)) {\r
     //\r
     // Read the last remaining word if exist\r
     //\r
-    *(UINT16*)Buffer = PciExpressRead16 (StartAddress);\r
+    *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress);\r
     StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
     Buffer = (UINT16*)Buffer + 1;\r
   }\r
 \r
-  if (EndAddress & 1) {\r
+  if (Size >= sizeof (UINT8)) {\r
     //\r
     // Read the last remaining byte if exist\r
     //\r
-    *(UINT8*)Buffer = PciExpressRead8 (StartAddress);\r
+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
   }\r
 \r
-  return Size;\r
+  return ReturnValue;\r
 }\r
 \r
 /**\r
@@ -1258,8 +1297,7 @@ PciExpressReadBuffer (
 \r
   If StartAddress > 0x0FFFFFFF, then ASSERT().\r
   If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
-  If (StartAddress + Size - 1)  > 0x0FFFFFFF, then ASSERT().\r
-  If Buffer is NULL, 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
                         Function and Register.\r
@@ -1277,52 +1315,68 @@ PciExpressWriteBuffer (
   IN      VOID                      *Buffer\r
   )\r
 {\r
-  UINTN                             EndAddress;\r
+  UINTN                             ReturnValue;\r
+\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
+\r
+  if (Size == 0) {\r
+    return 0;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
 \r
-  EndAddress = StartAddress + Size;\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
 \r
-  if ((StartAddress < EndAddress) && ((StartAddress & 1)!= 0)) {\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 (StartAddress < EndAddress && (StartAddress & 2)) {\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
     //\r
     // Write a word if StartAddress is word aligned\r
     //\r
     PciExpressWrite16 (StartAddress, *(UINT16*)Buffer);\r
     StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
     Buffer = (UINT16*)Buffer + 1;\r
   }\r
 \r
-  while (EndAddress - StartAddress >= 4) {\r
+  while (Size >= sizeof (UINT32)) {\r
     //\r
     // Write as many double words as possible\r
     //\r
     PciExpressWrite32 (StartAddress, *(UINT32*)Buffer);\r
     StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
     Buffer = (UINT32*)Buffer + 1;\r
   }\r
 \r
-  if (EndAddress & 2) {\r
+  if (Size >= sizeof (UINT16)) {\r
     //\r
     // Write the last remaining word if exist\r
     //\r
     PciExpressWrite16 (StartAddress, *(UINT16*)Buffer);\r
     StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
     Buffer = (UINT16*)Buffer + 1;\r
   }\r
 \r
-  if (EndAddress & 1) {\r
+  if (Size >= sizeof (UINT8)) {\r
     //\r
     // Write the last remaining byte if exist\r
     //\r
     PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);\r
   }\r
 \r
-  return Size;\r
+  return ReturnValue;\r
 }\r