*BaseSmbusLib: (new version)
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 11 May 2006 07:19:55 +0000 (07:19 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 11 May 2006 07:19:55 +0000 (07:19 +0000)
Complete function header, detailed description, ASSERT()s & pass smoke test in MRC of Lakeport package by replacing Smbus PPI.
*Device Patch Lib
Fix a bug in AppendDevicePathNode() (Solve Track #44 in Remodel PVCS). The original logic failed if the first device path was NULL.
*Performance Lib
Add PeiPerformanceHob & Performance protocol in spd file in EdkModule Package (Solve Tracker #41, #42 in Remodel PVCS).
*Hob Lib
Add detailed description for each Hob function.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@126 6f19259b-4bc3-4df7-8a09-765794883524

EdkModulePkg/EdkModulePkg.spd
MdePkg/Include/Library/DevicePathLib.h
MdePkg/Include/Library/HobLib.h
MdePkg/Library/BaseSmbusLib/BaseSmbusLib.msa
MdePkg/Library/BaseSmbusLib/SmbusLib.c
MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h [new file with mode: 0644]
MdePkg/Library/DxeCoreHobLib/HobLib.c
MdePkg/Library/DxeHobLib/HobLib.c
MdePkg/Library/PeiHobLib/HobLib.c
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c

index f2bdfa0..40c20d4 100644 (file)
@@ -469,6 +469,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
       <C_Name>gEfiCompatibleMemoryTestedGuid</C_Name>\r
       <Guid>0x64c475ef, 0x344b, 0x492c, 0x93, 0xad, 0xab, 0x9e, 0xb4, 0x39, 0x50, 0x4</Guid>\r
     </Entry>\r
+    <Entry Name="PeiPerformanceHob">\r
+      <C_Name>gPeiPerformanceHobGuid</C_Name>\r
+      <Guid>0xec4df5af, 0x4395, 0x4cc9, 0x94, 0xde, 0x77, 0x50, 0x6d, 0x12, 0xc7, 0xb8</Guid>\r
+    </Entry>\r
   </GuidDeclarations>\r
   <ProtocolDeclarations>\r
     <Entry Name="CustomizedDecompress">\r
@@ -571,6 +575,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
       <C_Name>gEfiIsaAcpiProtocolGuid</C_Name>\r
       <Guid>0x64a892dc, 0x5561, 0x4536, 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55</Guid>\r
     </Entry>\r
+    <Entry Name="Performance">\r
+      <C_Name>gPerformanceProtocolGuid</C_Name>\r
+      <Guid>0x76b6bdfa, 0x2acd, 0x4462, 0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37</Guid>\r
+    </Entry>\r
   </ProtocolDeclarations>\r
   <PpiDeclarations>\r
     <Entry Name="PeiInMemory">\r
index bedbd1c..b42a8fe 100644 (file)
@@ -74,24 +74,23 @@ AppendDevicePath (
 ;\r
 \r
 /**\r
-       This function appends the device path node SecondDevicePath\r
-       to every device path instance in FirstDevicePath.\r
+  This function appends the device path node SecondDevicePath\r
+  to every device path instance in FirstDevicePath.\r
 \r
-       @param  FirstDevicePath A pointer to a device path data structure.\r
-       \r
-       @param  SecondDevicePath A pointer to a single device path node.\r
+  @param  DevicePath A pointer to a device path data structure.\r
+  \r
+  @param  DevicePathNode A pointer to a single device path node.\r
 \r
-       @return\r
-       A pointer to the new device path.\r
-       If there is not enough temporary pool memory available to complete this function,\r
-       then NULL is returned.\r
+  @return A pointer to the new device path.\r
+  If there is not enough temporary pool memory available to complete this function,\r
+  then NULL is returned.\r
 \r
 **/\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 EFIAPI\r
 AppendDevicePathNode (\r
-  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,\r
-  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode\r
   )\r
 ;\r
 \r
index cac9c4f..9789c69 100644 (file)
 #define __HOB_LIB_H__\r
 \r
 /**\r
-       Returns the pointer to the HOB list.\r
+  Returns the pointer to the HOB list.\r
 \r
-       @return The pointer to the HOB list.\r
+  This function returns the pointer to first HOB in the list.\r
+\r
+  @return The pointer to the HOB list.\r
 \r
 **/\r
 VOID *\r
@@ -31,13 +33,19 @@ GetHobList (
 ;\r
 \r
 /**\r
-       This function searches the first instance of a HOB type from the starting HOB pointer. \r
-       If there does not exist such HOB type from the starting HOB pointer, it will return NULL. \r
+  Returns the next instance of a HOB type from the starting HOB.\r
+\r
+  This function searches the first instance of a HOB type from the starting HOB pointer. \r
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-       @param  Type The HOB type to return.\r
-       @param  HobStart The starting HOB pointer to search from.\r
+  @param  Type          The HOB type to return.\r
+  @param  HobStart      The starting HOB pointer to search from.\r
 \r
-       @return The next instance of a HOB type from the starting HOB.\r
+  @return The next instance of a HOB type from the starting HOB.\r
 \r
 **/\r
 VOID *\r
@@ -49,12 +57,14 @@ GetNextHob (
 ;\r
 \r
 /**\r
-       This function searches the first instance of a HOB type among the whole HOB list. \r
-       If there does not exist such HOB type in the HOB list, it will return NULL. \r
+  Returns the first instance of a HOB type among the whole HOB list.\r
 \r
-       @param  Type The HOB type to return.\r
+  This function searches the first instance of a HOB type among the whole HOB list. \r
+  If there does not exist such HOB type in the HOB list, it will return NULL. \r
 \r
-       @return The next instance of a HOB type from the starting HOB.\r
+  @param  Type          The HOB type to return.\r
+\r
+  @return The next instance of a HOB type from the starting HOB.\r
 \r
 **/\r
 VOID *\r
@@ -65,15 +75,22 @@ GetFirstHob (
 ;\r
 \r
 /**\r
-       This function searches the first instance of a HOB from the starting HOB pointer. \r
-       Such HOB should satisfy two conditions: \r
-       its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
-       If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
-\r
-       @param  Guid The GUID to match with in the HOB list.\r
-       @param  HobStart A pointer to a Guid.\r
-\r
-       @return The next instance of the matched GUID HOB from the starting HOB.\r
+  This function searches the first instance of a HOB from the starting HOB pointer. \r
+  Such HOB should satisfy two conditions: \r
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If Guid is NULL, then ASSERT().\r
+  If HobStart is NULL, then ASSERT().\r
+\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+  @param  HobStart      A pointer to a Guid.\r
+\r
+  @return The next instance of the matched GUID HOB from the starting HOB.\r
 \r
 **/\r
 VOID *\r
@@ -85,14 +102,17 @@ GetNextGuidHob (
 ;\r
 \r
 /**\r
-       This function searches the first instance of a HOB among the whole HOB list. \r
-       Such HOB should satisfy two conditions:\r
-       its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
-       If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  This function searches the first instance of a HOB among the whole HOB list. \r
+  Such HOB should satisfy two conditions:\r
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  If Guid is NULL, then ASSERT().\r
 \r
-       @param  Guid The GUID to match with in the HOB list.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
 \r
-       @return The first instance of the matched GUID HOB among the whole HOB list.\r
+  @return The first instance of the matched GUID HOB among the whole HOB list.\r
 \r
 **/\r
 VOID *\r
@@ -103,12 +123,18 @@ GetFirstGuidHob (
 ;\r
 \r
 /**\r
-       This function builds a HOB for a loaded PE32 module.\r
+  Builds a HOB for a loaded PE32 module.\r
+\r
+  This function builds a HOB for a loaded PE32 module.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If ModuleName is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-       @param  ModuleName The GUID File Name of the module.\r
-       @param  MemoryAllocationModule The 64 bit physical address of the module.\r
-       @param  ModuleLength The length of the module in bytes.\r
-       @param  EntryPoint The 64 bit physical address of the module\92s entry point.\r
+  @param  ModuleName              The GUID File Name of the module.\r
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.\r
+  @param  ModuleLength            The length of the module in bytes.\r
+  @param  EntryPoint              The 64 bit physical address of the module\92s entry point.\r
 \r
 **/\r
 VOID\r
@@ -122,12 +148,17 @@ BuildModuleHob (
 ;\r
 \r
 /**\r
-       Builds a HOB that describes a chunk of system memory.\r
+  Builds a HOB that describes a chunk of system memory.\r
 \r
-       @param  ResourceType The type of resource described by this HOB.\r
-       @param  ResourceAttribute The resource attributes of the memory described by this HOB.\r
-       @param  PhysicalStart The 64 bit physical address of memory described by this HOB.\r
-       @param  NumberOfBytes The length of the memory described by this HOB in bytes.\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
 \r
 **/\r
 VOID\r
@@ -141,13 +172,21 @@ BuildResourceDescriptorHob (
 ;\r
 \r
 /**\r
-       This function builds a customized HOB tagged with a GUID for identification \r
-       and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  Builds a GUID HOB with a certain data length.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification \r
+  and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
 \r
-       @param  Guid The GUID to tag the customized HOB.\r
-       @param  DataLength The size of the data payload for the GUID HOB.\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
-       @return The start address of GUID HOB data.\r
+  @return The start address of GUID HOB data.\r
 \r
 **/\r
 VOID *\r
@@ -159,14 +198,23 @@ BuildGuidHob (
 ;\r
 \r
 /**\r
-       This function builds a customized HOB tagged with a GUID for identification, \r
-       copies the input data to the HOB data field, and returns the start address of GUID HOB data.\r
+  Copies a data buffer to a newly-built HOB.\r
 \r
-       @param  Guid The GUID to tag the customized HOB.\r
-       @param  Data The data to be copied into the data field of the GUID HOB.\r
-       @param  DataLength The size of the data payload for the GUID HOB.\r
+  This function builds a customized HOB tagged with a GUID for identification,\r
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If Data is NULL and DataLength > 0, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
 \r
-       @return The start address of GUID HOB data.\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  Data          The data to be copied into the data field of the GUID HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
+\r
+  @return The start address of GUID HOB data.\r
 \r
 **/\r
 VOID *\r
@@ -179,10 +227,15 @@ BuildGuidDataHob (
 ;\r
 \r
 /**\r
-       Builds a Firmware Volume HOB.\r
+  Builds a Firmware Volume HOB.\r
+\r
+  This function builds a Firmware Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-       @param  BaseAddress The base address of the Firmware Volume.\r
-       @param  Length The size of the Firmware Volume in bytes.\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -194,10 +247,15 @@ BuildFvHob (
 ;\r
 \r
 /**\r
-       Builds a Capsule Volume HOB.\r
+  Builds a Capsule Volume HOB.\r
 \r
-       @param  BaseAddress The base address of the Capsule Volume.\r
-       @param  Length The size of the Capsule Volume in bytes.\r
+  This function builds a Capsule Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Capsule Volume.\r
+  @param  Length        The size of the Capsule Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -209,10 +267,15 @@ BuildCvHob (
 ;\r
 \r
 /**\r
-       Builds a HOB for the CPU.\r
+  Builds a HOB for the CPU.\r
+\r
+  This function builds a HOB for the CPU.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-       @param  SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
-       @param  SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.\r
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.\r
 \r
 **/\r
 VOID\r
@@ -224,10 +287,15 @@ BuildCpuHob (
 ;\r
 \r
 /**\r
-       Builds a HOB for the Stack.\r
+  Builds a HOB for the Stack.\r
 \r
-       @param  BaseAddress The 64 bit physical address of the Stack.\r
-       @param  Length The length of the stack in bytes.\r
+  This function builds a HOB for the stack.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
 \r
 **/\r
 VOID\r
@@ -239,11 +307,16 @@ BuildStackHob (
 ;\r
 \r
 /**\r
-       Builds a HOB for the BSP store.\r
+  Builds a HOB for the BSP store.\r
+\r
+  This function builds a HOB for BSP store.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-       @param  BaseAddress The 64 bit physical address of the BSP.\r
-       @param  Length The length of the BSP store in bytes.\r
-       @param  MemoryType Type of memory allocated by this HOB.\r
+  @param  BaseAddress   The 64 bit physical address of the BSP.\r
+  @param  Length        The length of the BSP store in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
@@ -256,11 +329,16 @@ BuildBspStoreHob (
 ;\r
 \r
 /**\r
-       Builds a HOB for the memory allocation.\r
+  Builds a HOB for the memory allocation.\r
+\r
+  This function builds a HOB for the memory allocation.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-       @param  BaseAddress The 64 bit physical address of the memory.\r
-       @param  Length The length of the memory allocation in bytes.\r
-       @param  MemoryType Type of memory allocated by this HOB.\r
+  @param  BaseAddress   The 64 bit physical address of the memory.\r
+  @param  Length        The length of the memory allocation in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
index 00c2aa4..25b8f51 100644 (file)
@@ -32,7 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     <Updated>2006-03-19 15:17</Updated>\r
   </MsaLibHeader>\r
   <LibraryClassDefinitions>\r
-    <LibraryClass Usage="ALWAYS_PRODUCED">SmBusLib</LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_PRODUCED">SmbusLib</LibraryClass>\r
     <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>\r
     <LibraryClass Usage="ALWAYS_CONSUMED">IoLib</LibraryClass>\r
     <LibraryClass Usage="ALWAYS_CONSUMED">PciLib</LibraryClass>\r
index 5aad978..29c09e7 100644 (file)
   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
 \r
-  Module Name:  SmbusLib.h\r
+  Module Name:  SmbusLib.c\r
 \r
 **/\r
 \r
-RETURN_STATUS\r
-EFIAPI\r
-BaseSmBusLibConstructor (\r
-  IN      VOID                      *Param1,\r
-  IN      VOID                      *Param2\r
-  )\r
-{\r
-  return RETURN_SUCCESS;\r
-}\r
+#include "SmbusLibRegisters.h"\r
 \r
-//\r
-// BUGBUG: use PCD to retrieve BUS, DEV, FUNC & OFFSET for SMBUS host BAR\r
-//\r
-#define SMBUS_HOST_BUS              0\r
-#define SMBUS_HOST_DEV              31\r
-#define SMBUS_HOST_FUNC             3\r
-#define SMBUS_HOST_SMB_BASE         0x20\r
-\r
-//\r
-// Offsets of registers for SMBUS controller\r
-//\r
-#define R_HST_STS                   0\r
-#define R_HST_CNT                   2\r
-#define R_HST_CMD                   3\r
-#define R_XMIT_SLVA                 4\r
-#define R_HST_D0                    5\r
-#define R_HST_D1                    6\r
-#define R_HOST_BLOCK_DB             7\r
-#define R_PEC                       8\r
-#define R_RCV_SLVA                  9\r
-#define R_SLV_DATA                  0x0a\r
-#define R_AUX_STS                   0x0c\r
-#define R_AUX_CTL                   0x0d\r
-#define R_SMLINK_PIN_CTL            0x0e\r
-#define R_SMBUS_PIN_CTL             0x0f\r
-#define R_SLV_STS                   0x10\r
-#define R_SLV_CMD                   0x11\r
-#define R_NOTIFY_DADDR              0x14\r
-#define R_NOTIFY_DLOW               0x16\r
-#define R_NOTIFY_DHIGH              0x17\r
+#define SMBUS_LIB_SLAVE_ADDRESS(SmBusAddress)      (((SmBusAddress) >> 1)  & 0x7f)\r
+#define SMBUS_LIB_COMMAND(SmBusAddress)            (((SmBusAddress) >> 8)  & 0xff)\r
+#define SMBUS_LIB_LENGTH(SmBusAddress)             (((SmBusAddress) >> 16) & 0x1f)\r
+#define SMBUS_LIB_PEC(SmBusAddress)     ((BOOLEAN) (((SmBusAddress) & SMBUS_LIB_PEC_BIT) != 0))\r
+#define SMBUS_LIB_RESEARVED(SmBusAddress)          ((SmBusAddress) & ~(((1 << 21) - 2) | SMBUS_LIB_PEC_BIT))\r
 \r
 //\r
-// Bits in HST_STS\r
+// Replaced by PCD\r
 //\r
-#define B_HST_STS_DS                0x80\r
-#define B_HST_STS_INUSE             0x40\r
-#define B_HST_STS_SMBALERT          0x20\r
-#define B_HST_STS_FAILED            0x10\r
-#define B_HST_STS_BUS_ERR           0x08\r
-#define B_HST_STS_DEV_ERR           0x04\r
-#define B_HST_STS_INTR              0x02\r
-#define B_HST_STS_BUSY              0x01\r
-#define B_HST_STS_ERR               ( B_HST_STS_BUS_ERR   | \\r
-                                      B_HST_STS_DEV_ERR   | \\r
-                                      B_HST_STS_FAILED )\r
-#define B_HST_STS_ALL               ( B_HST_STS_DS        | \\r
-                                      B_HST_STS_INUSE     | \\r
-                                      B_HST_STS_SMBALERT  | \\r
-                                      B_HST_STS_ERR       | \\r
-                                      B_HST_STS_INTR )\r
+#define ICH_SMBUS_BASE_ADDRESS               0xEFA0\r
 \r
-//\r
-// Bits in HST_CNT\r
-//\r
-#define B_HST_CNT_PEC               0x80\r
-#define B_HST_CNT_START             0x40\r
-#define B_HST_CNT_LAST_BYTE         0x20\r
-#define B_HST_CNT_SMB_CMD           0x1c\r
-#define B_HST_CNT_KILL              0x02\r
-#define B_HST_CNT_INTREN            0x01\r
+/**\r
+  Reads an 8-bit SMBUS register on ICH.\r
 \r
-//\r
-// SMBUS Protocols\r
-//\r
-#define B_SMB_CMD_QUICK             0\r
-#define B_SMB_CMD_BYTE              1\r
-#define B_SMB_CMD_BYTE_DATA         2\r
-#define B_SMB_CMD_WORD_DATA         3\r
-#define B_SMB_CMD_PROCESS_CALL      4\r
-#define B_SMB_CMD_BLOCK             5\r
-#define B_SMB_CMD_I2C               6\r
-#define B_SMB_CMD_BLOCK_PROCESS     7\r
+  This internal function reads an SMBUS register specified by Offset.\r
 \r
-//\r
-// Bits in AUX_CTL\r
-//\r
-#define B_AUX_CTL_E32B              0x02\r
-#define B_AUX_CTL_AAC               0x01\r
+  @param  Offset  The offset of SMBUS register.\r
 \r
-//\r
-// SMBUS Rd/Wr control\r
-//\r
-#define B_SMBUS_READ                1\r
-#define B_SMBUS_WRITE               0\r
+  @return The value read.\r
 \r
-static\r
-UINT16\r
-EFIAPI\r
-GetSmBusIOBaseAddress (\r
-  VOID\r
+**/\r
+UINT8\r
+InternalSmBusIoRead8 (\r
+  IN UINTN      Offset\r
   )\r
 {\r
-  UINT32                            SmbusBar;\r
-\r
-  SmbusBar = PciRead32 (\r
-               PCI_LIB_ADDRESS (\r
-                 SMBUS_HOST_BUS,\r
-                 SMBUS_HOST_DEV,\r
-                 SMBUS_HOST_FUNC,\r
-                 SMBUS_HOST_SMB_BASE\r
-                 )\r
-               );\r
-  ASSERT ((SmbusBar & 0xffff001f) == 1);\r
-  return (UINT16)(SmbusBar & ~1);\r
+  return IoRead8 (ICH_SMBUS_BASE_ADDRESS + Offset);\r
 }\r
 \r
-static\r
-BOOLEAN\r
-EFIAPI\r
-SmBusAcquire (\r
-  IN      UINT16                    SmBusBase\r
-  )\r
-{\r
-  UINT8                             HstSts;\r
+/**\r
+  Writes an 8-bit SMBUS register on ICH.\r
 \r
-  HstSts = IoRead8 (SmBusBase + R_HST_STS);\r
-  if (HstSts & B_HST_STS_INUSE) {\r
-    return FALSE;\r
-  }\r
+  This internal function writes an SMBUS register specified by Offset.\r
 \r
-  //\r
-  // BUGBUG: Dead loop may occur here\r
-  //\r
-  while (HstSts & B_HST_STS_BUSY) {\r
-    ASSERT (HstSts & B_HST_STS_INUSE);\r
-    HstSts = IoRead8 (SmBusBase + R_HST_STS);\r
-  }\r
-  return TRUE;\r
-}\r
+  @param  Offset  The offset of SMBUS register.\r
+  @param  Value   The value to write to SMBUS register.\r
 \r
-static\r
-VOID\r
-EFIAPI\r
-SmBusStart (\r
-  IN      UINT16                    SmBusBase,\r
-  IN      UINT8                     SmBusProtocol,\r
-  IN      UINT8                     SlaveAddress\r
+  @return The value written the SMBUS register.\r
+\r
+**/\r
+UINT8\r
+InternalSmBusIoWrite8 (\r
+  IN UINTN      Offset,\r
+  IN UINT8      Value\r
   )\r
 {\r
-  IoWrite8 (SmBusBase + R_XMIT_SLVA, SlaveAddress);\r
-  IoWrite8 (\r
-    SmBusBase + R_HST_CNT,\r
-    IoBitFieldWrite8 (SmBusBase + R_HST_CNT, 2, 4, SmBusProtocol) |\r
-    B_HST_CNT_START\r
-    );\r
+  return IoWrite8 (ICH_SMBUS_BASE_ADDRESS + Offset, Value);\r
 }\r
 \r
-static\r
-UINT8\r
-EFIAPI\r
-SmBusWait (\r
-  IN      UINT16                    SmBusBase\r
+/**\r
+  Acquires the ownership of SMBUS.\r
+\r
+  This internal function reads the host state register.\r
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;\r
+  Otherwise, it performs some basic initializations and returns\r
+  RETURN_SUCCESS. \r
+\r
+  @retval RETURN_SUCCESS    The SMBUS command was executed successfully.\r
+  @retval RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.\r
+\r
+**/\r
+RETURN_STATUS\r
+InternalSmBusAcquire (\r
+  VOID \r
   )\r
 {\r
-  UINT8                             HstSts;\r
+  UINT8   HostStatus;\r
 \r
-  while (((HstSts = IoRead8 (SmBusBase + R_HST_STS)) & B_HST_STS_INTR) == 0);\r
-  return HstSts;\r
+  HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);\r
+  if ((HostStatus & SMBUS_B_INUSE_STS) != 0) {\r
+    return RETURN_TIMEOUT;\r
+  } else if ((HostStatus & SMBUS_B_HOST_BUSY) != 0) {\r
+    //\r
+    // Clear Status Register and exit\r
+    //\r
+    InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
+    return RETURN_TIMEOUT;\r
+  }\r
+  //\r
+  // Clear byte pointer of 32-byte buffer.\r
+  //\r
+  InternalSmBusIoRead8 (SMBUS_R_HST_CTL);\r
+  //\r
+  // Clear BYTE_DONE status\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_BYTE_DONE_STS);\r
+  \r
+  return RETURN_SUCCESS;\r
 }\r
 \r
-static\r
-VOID\r
-EFIAPI\r
-SmBusCleanup (\r
-  IN      UINT16                    SmBusBase\r
+/**\r
+  Waits until the completion of SMBUS transaction.\r
+\r
+  This internal function waits until the transaction of SMBUS is over\r
+  by polling the INTR bit of Host status register.\r
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;\r
+  Otherwise, it performs some basic initializations and returns\r
+  RETURN_SUCCESS. \r
+\r
+  @retval RETURN_SUCCESS      The SMBUS command was executed successfully.\r
+  @retval RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).\r
+  @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected\r
+                              in the Host Status Register bit.  Device errors are\r
+                              a result of a transaction collision, illegal command field,\r
+                              unclaimed cycle (host initiated), or bus errors (collisions).\r
+\r
+**/\r
+RETURN_STATUS\r
+InternalSmBusWait (\r
+  VOID \r
   )\r
 {\r
-  IoWrite8 (SmBusBase + R_HST_STS, B_HST_STS_ALL);\r
+  UINT8   HostStatus;\r
+  UINT8   AuxiliaryStatus;\r
+  BOOLEAN First;\r
+  First = TRUE;\r
+\r
+  do {\r
+    //\r
+    // Poll INTR bit of host status register.\r
+    //\r
+    HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);\r
+  } while ((HostStatus & (SMBUS_B_INTR | SMBUS_B_ERROR | SMBUS_B_BYTE_DONE_STS)) == 0);\r
+  \r
+  if ((HostStatus & SMBUS_B_ERROR) == 0) {\r
+    return RETURN_SUCCESS;\r
+  }\r
+  //\r
+  // Clear error bits of host status register\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_ERROR);\r
+  //\r
+  // Read auxiliary status register to judge CRC error.\r
+  //\r
+  AuxiliaryStatus = InternalSmBusIoRead8 (SMBUS_R_AUX_STS);\r
+  if ((AuxiliaryStatus & SMBUS_B_CRCE) != 0) {\r
+    return RETURN_CRC_ERROR;\r
+  }\r
+\r
+  return RETURN_DEVICE_ERROR;\r
 }\r
 \r
-static\r
-RETURN_STATUS\r
+/**\r
+  Executes an SMBUS quick read/write command.\r
+\r
+  This internal function executes an SMBUS quick read/write command\r
+  on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address field of SmBusAddress is required.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+**/\r
+VOID\r
 EFIAPI\r
-SmBusQuick (\r
-  IN      UINT8                     SmBusAddress\r
+InternalSmBusQuick (\r
+  IN  UINTN                     SmBusAddress,\r
+  OUT RETURN_STATUS             *Status       OPTIONAL\r
   )\r
 {\r
-  RETURN_STATUS                     Status;\r
-  UINT16                            SmBusBase;\r
+  RETURN_STATUS   ReturnStatus;\r
 \r
-  SmBusBase = GetSmBusIOBaseAddress ();\r
-  if (!SmBusAcquire (SmBusBase)) {\r
-    return RETURN_TIMEOUT;\r
+  ReturnStatus = InternalSmBusAcquire ();\r
+  if (RETURN_ERROR (ReturnStatus)) {\r
+    goto Done;\r
   }\r
\r
+  //\r
+  // Set Command register\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, 0);\r
+  //\r
+  // Set Auxiliary Control register\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, 0);\r
+  //\r
+  // Set SMBus slave address for the device to send/receive from\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
+  //\r
+  // Set Control Register (Initiate Operation, Interrupt disabled)\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, SMBUS_V_SMB_CMD_QUICK + SMBUS_B_START);\r
 \r
-  SmBusStart (SmBusAddress, B_SMB_CMD_QUICK, SmBusAddress);\r
-  if (SmBusWait (SmBusAddress) & B_HST_STS_ERR) {\r
-    Status = RETURN_DEVICE_ERROR;\r
-  } else {\r
-    Status = RETURN_SUCCESS;\r
-  }\r
+  //\r
+  // Wait for the end\r
+  //\r
+  ReturnStatus = InternalSmBusWait ();\r
 \r
-  SmBusCleanup (SmBusAddress);\r
-  return Status;\r
+  //\r
+  // Clear status register and exit\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
+\r
+Done:\r
+  if (Status != NULL) {\r
+    *Status = ReturnStatus;\r
+  }\r
 }\r
 \r
+/**\r
+  Executes an SMBUS quick read command.\r
+\r
+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address field of SmBusAddress is required.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If PEC is set in SmBusAddress, then ASSERT().\r
+  If Command in SmBusAddress is not zero, then ASSERT().\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+**/\r
 VOID\r
 EFIAPI\r
 SmBusQuickRead (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN                     SmBusAddress,\r
+  OUT RETURN_STATUS             *Status       OPTIONAL\r
   )\r
 {\r
-  RETURN_STATUS                     RetStatus;\r
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  ASSERT ((SmBusAddress & ~0xfe) == 0);\r
-  RetStatus = SmBusQuick ((UINT8)SmBusAddress | B_SMBUS_READ);\r
-  if (Status) {\r
-    *Status = RetStatus;\r
-  }\r
+  InternalSmBusQuick (SmBusAddress | SMBUS_B_READ, Status);\r
 }\r
 \r
-BOOLEAN\r
+/**\r
+  Executes an SMBUS quick write command.\r
+\r
+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address field of SmBusAddress is required.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If PEC is set in SmBusAddress, then ASSERT().\r
+  If Command in SmBusAddress is not zero, then ASSERT().\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+**/\r
+VOID\r
 EFIAPI\r
 SmBusQuickWrite (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN                     SmBusAddress,\r
+  OUT RETURN_STATUS             *Status       OPTIONAL\r
   )\r
 {\r
-  RETURN_STATUS                     RetStatus;\r
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
 \r
-  ASSERT ((SmBusAddress & ~0xfe) == 0);\r
-  RetStatus = SmBusQuick ((UINT8)SmBusAddress | B_SMBUS_WRITE);\r
-  if (Status) {\r
-    *Status = RetStatus;\r
-  }\r
-  return (BOOLEAN)!RETURN_ERROR (RetStatus);\r
+  InternalSmBusQuick (SmBusAddress | SMBUS_B_WRITE, Status);\r
 }\r
 \r
-static\r
+/**\r
+  Executes an SMBUS byte or word command.\r
+\r
+  This internal function executes an .\r
+  Only the SMBUS slave address field of SmBusAddress is required.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+\r
+  @param  HostControl     The value of Host Control Register to set.  \r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The byte/word write to the SMBUS.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The byte/word read from the SMBUS.\r
+\r
+**/\r
 UINT16\r
-EFIAPI\r
-SmBusByteWord (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT16                    Value,\r
-  IN      UINT8                     SmBusProtocol,\r
-  OUT     RETURN_STATUS             *Status\r
+InternalSmBusByteWord (\r
+  IN  UINT8                     HostControl,\r
+  IN  UINTN                     SmBusAddress,\r
+  IN  UINT16                    Value,\r
+  OUT RETURN_STATUS             *Status\r
   )\r
 {\r
-  RETURN_STATUS                     RetStatus;\r
-  UINT16                            SmBusBase;\r
+  RETURN_STATUS                 ReturnStatus;\r
+  UINT8                         AuxiliaryControl;\r
 \r
-  if (Status == NULL) {\r
-    Status = &RetStatus;\r
+  ReturnStatus = InternalSmBusAcquire ();\r
+  if (RETURN_ERROR (ReturnStatus)) {\r
+    goto Done;\r
   }\r
 \r
-  SmBusBase = GetSmBusIOBaseAddress ();\r
-  if (!SmBusAcquire (SmBusBase)) {\r
-    *Status = RETURN_TIMEOUT;\r
-    return Value;\r
+  AuxiliaryControl = 0;\r
+  if (SMBUS_LIB_PEC (SmBusAddress)) {\r
+    AuxiliaryControl |= SMBUS_B_AAC;\r
+    HostControl      |= SMBUS_B_PEC_EN;\r
   }\r
\r
+  //\r
+  // Set commond register\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
 \r
-  IoWrite8 (SmBusBase + R_HST_CMD, (UINT8)(SmBusAddress >> 8));\r
-  IoWrite8 (SmBusBase + R_HST_D0, (UINT8)Value);\r
-  IoWrite8 (SmBusBase + R_HST_D1, (UINT8)(Value >> 8));\r
-  if ((INTN)SmBusAddress < 0) {\r
-    IoOr8 (SmBusBase + R_HST_CNT, B_HST_CNT_PEC);\r
-    IoOr8 (SmBusBase + R_AUX_CTL, B_AUX_CTL_AAC);\r
-  } else {\r
-    IoAnd8 (SmBusBase + R_HST_CNT, (UINT8)~B_HST_CNT_PEC);\r
-    IoAnd8 (SmBusBase + R_AUX_CTL, (UINT8)~B_AUX_CTL_AAC);\r
-  }\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) Value);\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_D1, (UINT8) (Value >> 8));\r
+\r
+  //\r
+  // Set Auxiliary Control Regiester.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
+  //\r
+  // Set SMBus slave address for the device to send/receive from.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
+  //\r
+  // Set Control Register (Initiate Operation, Interrupt disabled)\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
+\r
+  //\r
+  // Wait for the end\r
+  //\r
+  ReturnStatus = InternalSmBusWait ();\r
\r
+  Value  = InternalSmBusIoRead8 (SMBUS_R_HST_D1) << 8;\r
+  Value |= InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
 \r
-  SmBusStart (SmBusBase, SmBusProtocol, (UINT8)SmBusAddress);\r
+  //\r
+  // Clear status register and exit\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
 \r
-  if (SmBusWait (SmBusBase) & B_HST_STS_ERR) {\r
-    *Status = RETURN_DEVICE_ERROR;\r
-  } else {\r
-    *Status = RETURN_SUCCESS;\r
-    Value = IoRead8 (SmBusBase + R_HST_D0);\r
-    Value |= (UINT16)IoRead8 (SmBusBase + R_HST_D1) << 8;\r
+Done:\r
+  if (Status != NULL) {\r
+    *Status = ReturnStatus;\r
   }\r
 \r
-  SmBusCleanup (SmBusBase);\r
   return Value;\r
 }\r
 \r
+/**\r
+  Executes an SMBUS receive byte command.\r
+\r
+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address field of SmBusAddress is required.\r
+  The byte received from the SMBUS is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Command in SmBusAddress is not zero, then ASSERT().\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The byte received from the SMBUS.\r
+\r
+**/\r
 UINT8\r
 EFIAPI\r
 SmBusReceiveByte (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfe | MAX_BIT)) == 0);\r
-  return (UINT8)SmBusByteWord (\r
-                  SmBusAddress | B_SMBUS_READ,\r
-                  0,\r
-                  B_SMB_CMD_BYTE,\r
-                  Status\r
-                  );\r
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return (UINT8) InternalSmBusByteWord (\r
+                   SMBUS_V_SMB_CMD_BYTE,\r
+                   SmBusAddress | SMBUS_B_READ,\r
+                   0,\r
+                   Status\r
+                   );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS send byte command.\r
+\r
+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.\r
+  The byte specified by Value is sent.\r
+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Command in SmBusAddress is not zero, then ASSERT().\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The 8-bit value to send.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The parameter of Value.\r
+\r
+**/\r
 UINT8\r
 EFIAPI\r
 SmBusSendByte (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT8                     Value,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  IN  UINT8          Value,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfe | MAX_BIT)) == 0);\r
-  return (UINT8)SmBusByteWord (\r
-                  SmBusAddress | B_SMBUS_WRITE,\r
-                  Value,\r
-                  B_SMB_CMD_BYTE,\r
-                  Status\r
-                  );\r
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return (UINT8) InternalSmBusByteWord (\r
+                   SMBUS_V_SMB_CMD_BYTE,\r
+                   SmBusAddress | SMBUS_B_WRITE,\r
+                   Value,\r
+                   Status\r
+                   );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS read data byte command.\r
+\r
+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  The 8-bit value read from the SMBUS is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The byte read from the SMBUS.\r
+\r
+**/\r
 UINT8\r
 EFIAPI\r
 SmBusReadDataByte (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffe | MAX_BIT)) == 0);\r
-  return (UINT8)SmBusByteWord (\r
-                  SmBusAddress | B_SMBUS_READ,\r
-                  0,\r
-                  B_SMB_CMD_BYTE_DATA,\r
-                  Status\r
-                  );\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return (UINT8) InternalSmBusByteWord (\r
+                   SMBUS_V_SMB_CMD_BYTE_DATA,\r
+                   SmBusAddress | SMBUS_B_READ,\r
+                   0,\r
+                   Status\r
+                   );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS write data byte command.\r
+\r
+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.\r
+  The 8-bit value specified by Value is written.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  Value is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The 8-bit value to write.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The parameter of Value.\r
+\r
+**/\r
 UINT8\r
 EFIAPI\r
 SmBusWriteDataByte (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT8                     Value,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  IN  UINT8          Value,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT (((UINT32)SmBusAddress & ~(0xfffe | MAX_BIT)) == 0);\r
-  return (UINT8)SmBusByteWord (\r
-                  SmBusAddress | B_SMBUS_WRITE,\r
-                  Value,\r
-                  B_SMB_CMD_BYTE_DATA,\r
-                  Status\r
-                  );\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return (UINT8) InternalSmBusByteWord (\r
+                   SMBUS_V_SMB_CMD_BYTE_DATA,\r
+                   SmBusAddress | SMBUS_B_WRITE,\r
+                   Value,\r
+                   Status\r
+                   );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS read data word command.\r
+\r
+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  The 16-bit value read from the SMBUS is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+  \r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The byte read from the SMBUS.\r
+\r
+**/\r
 UINT16\r
 EFIAPI\r
 SmBusReadDataWord (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffe | MAX_BIT)) == 0);\r
-  return SmBusByteWord (\r
-           SmBusAddress | B_SMBUS_READ,\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusByteWord (\r
+           SMBUS_V_SMB_CMD_WORD_DATA,\r
+           SmBusAddress | SMBUS_B_READ,\r
            0,\r
-           B_SMB_CMD_WORD_DATA,\r
            Status\r
            );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS write data word command.\r
+\r
+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.\r
+  The 16-bit value specified by Value is written.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  Value is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The 16-bit value to write.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The parameter of Value.\r
+\r
+**/\r
 UINT16\r
 EFIAPI\r
 SmBusWriteDataWord (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT16                    Value,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  IN  UINT16         Value,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffe | MAX_BIT)) == 0);\r
-  return SmBusByteWord (\r
-           SmBusAddress | B_SMBUS_WRITE,\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusByteWord (\r
+           SMBUS_V_SMB_CMD_WORD_DATA,\r
+           SmBusAddress | SMBUS_B_WRITE,\r
            Value,\r
-           B_SMB_CMD_WORD_DATA,\r
            Status\r
            );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS process call command.\r
+\r
+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.\r
+  The 16-bit value specified by Value is written.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  The 16-bit value returned by the process call command is returned.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Value           The 16-bit value to write.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The 16-bit value returned by the process call command.\r
+\r
+**/\r
 UINT16\r
 EFIAPI\r
 SmBusProcessCall (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT16                    Value,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  IN  UINT16         Value,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffe | MAX_BIT)) == 0);\r
-  return SmBusByteWord (\r
-           SmBusAddress | B_SMBUS_WRITE,\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusByteWord (\r
+           SMBUS_V_SMB_CMD_PROCESS_CALL,\r
+           SmBusAddress | SMBUS_B_WRITE,\r
            Value,\r
-           B_SMB_CMD_PROCESS_CALL,\r
            Status\r
            );\r
 }\r
 \r
-static\r
+/**\r
+  Executes an SMBUS block command.\r
+\r
+  Executes an SMBUS block read, block write and block write-block read command\r
+  on the SMBUS device specified by SmBusAddress.\r
+  Bytes are read from the SMBUS and stored in Buffer.\r
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.\r
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
+\r
+  @param  HostControl     The value of Host Control Register to set.  \r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.\r
+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The number of bytes read from the SMBUS.\r
+\r
+**/\r
 UINTN\r
-EFIAPI\r
-SmBusBlock (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      UINT8                     SmBusProtocol,\r
-  IN      VOID                      *InBuffer,\r
-  OUT     VOID                      *OutBuffer,\r
-  OUT     RETURN_STATUS             *Status\r
+InternalSmBusBlock (\r
+  IN  UINT8                     HostControl,\r
+  IN  UINTN                     SmBusAddress,\r
+  IN  UINT8                     *OutBuffer,\r
+  OUT UINT8                     *InBuffer,\r
+  OUT RETURN_STATUS             *Status\r
   )\r
 {\r
-  RETURN_STATUS                     RetStatus;\r
-  UINT16                            SmBusBase;\r
-  UINTN                             Index;\r
-  UINTN                             BytesCount;\r
+  RETURN_STATUS                 ReturnStatus;\r
+  UINTN                         Index;\r
+  UINTN                         BytesCount;\r
+  UINT8                         AuxiliaryControl;\r
 \r
-  BytesCount = (UINT8)(SmBusAddress >> 16);\r
-  ASSERT (BytesCount <= 32);\r
+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress) + 1;\r
 \r
-  if (Status == NULL) {\r
-    Status = &RetStatus;\r
+  ReturnStatus = InternalSmBusAcquire ();\r
+  if (RETURN_ERROR (ReturnStatus)) {\r
+    goto Done;\r
   }\r
-\r
-  SmBusBase = GetSmBusIOBaseAddress ();\r
-  if (!SmBusAcquire (SmBusBase)) {\r
-    *Status = RETURN_TIMEOUT;\r
-    return 0;\r
+  \r
+  AuxiliaryControl = SMBUS_B_E32B;\r
+  if (SMBUS_LIB_PEC (SmBusAddress)) {\r
+    AuxiliaryControl |= SMBUS_B_AAC;\r
+    HostControl      |= SMBUS_B_PEC_EN;\r
   }\r
 \r
-  IoWrite8 (SmBusBase + R_HST_CMD, (UINT8)(SmBusAddress >> 8));\r
-  IoWrite8 (SmBusBase + R_HST_D0, (UINT8)BytesCount);\r
-  if ((INTN)SmBusAddress < 0) {\r
-    IoOr8 (SmBusBase + R_HST_CNT, B_HST_CNT_PEC);\r
-    IoOr8 (SmBusBase + R_AUX_CTL, B_AUX_CTL_AAC);\r
-  } else {\r
-    IoAnd8 (SmBusBase + R_HST_CNT, (UINT8)~B_HST_CNT_PEC);\r
-    IoAnd8 (SmBusBase + R_AUX_CTL, (UINT8)~B_AUX_CTL_AAC);\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
+\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) BytesCount);\r
+\r
+  if (OutBuffer != NULL) {\r
+    for (Index = 0; Index < BytesCount; Index++) {\r
+      InternalSmBusIoWrite8 (SMBUS_R_HOST_BLOCK_DB, OutBuffer[Index]);\r
+    }\r
   }\r
+  //\r
+  // Set Auxiliary Control Regiester.\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
+  //\r
+  // Set SMBus slave address for the device to send/receive from\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
+  //\r
+  // Set Control Register (Initiate Operation, Interrupt disabled)\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
 \r
   //\r
-  // BUGBUG: E32B bit does not exist in ICH3 or earlier\r
+  // Wait for the end\r
   //\r
-  IoOr8 (SmBusBase + R_AUX_CTL, B_AUX_CTL_E32B);\r
-  ASSERT (IoRead8 (SmBusBase + R_AUX_CTL) & B_AUX_CTL_E32B);\r
-  for (Index = 0; InBuffer != NULL && Index < BytesCount; Index++) {\r
-    IoWrite8 (SmBusBase + R_HOST_BLOCK_DB, ((UINT8*)InBuffer)[Index]);\r
+  ReturnStatus = InternalSmBusWait ();\r
+  if (RETURN_ERROR (ReturnStatus)) {\r
+    goto Done;\r
   }\r
 \r
-  SmBusStart (SmBusBase, SmBusProtocol, (UINT8)SmBusAddress);\r
-\r
-  if (SmBusWait (SmBusBase) & B_HST_STS_ERR) {\r
-    *Status = RETURN_DEVICE_ERROR;\r
-  } else {\r
-    *Status = RETURN_SUCCESS;\r
-    BytesCount = IoRead8 (SmBusBase + R_HST_D0);\r
-    for (Index = 0; OutBuffer != NULL && Index < BytesCount; Index++) {\r
-      ((UINT8*)OutBuffer)[Index] = IoRead8 (SmBusBase + R_HOST_BLOCK_DB);\r
+  BytesCount = InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
+  if (InBuffer != NULL) {\r
+    for (Index = 0; Index < BytesCount; Index++) {\r
+      InBuffer[Index] = InternalSmBusIoRead8 (SMBUS_R_HOST_BLOCK_DB);\r
     }\r
   }\r
 \r
-  SmBusCleanup (SmBusBase);\r
+  //\r
+  // Clear status register and exit\r
+  //\r
+  InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
+\r
+Done:\r
+  if (Status != NULL) {\r
+    *Status = ReturnStatus;\r
+  }\r
+\r
   return BytesCount;\r
 }\r
 \r
+/**\r
+  Executes an SMBUS read block command.\r
+\r
+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.\r
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
+  Bytes are read from the SMBUS and stored in Buffer.\r
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.\r
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
+  If Length in SmBusAddress is not zero, then ASSERT().\r
+  If Buffer is NULL, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The number of bytes read.\r
+\r
+**/\r
 UINTN\r
 EFIAPI\r
 SmBusReadBlock (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     VOID                      *Buffer,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  OUT VOID           *Buffer,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffffe | MAX_BIT)) == 0);\r
-  return SmBusBlock (\r
-           SmBusAddress | B_SMBUS_READ,\r
-           B_SMB_CMD_BLOCK,\r
+  ASSERT (Buffer != NULL);\r
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusBlock (\r
+           SMBUS_V_SMB_CMD_BLOCK,\r
+           SmBusAddress | SMBUS_B_READ,\r
            NULL,\r
            Buffer,\r
            Status\r
            );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS write block command.\r
+\r
+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.\r
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
+  Bytes are written to the SMBUS from Buffer.\r
+  The number of bytes written is returned, and will never return a value larger than 32-bytes.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.  \r
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().\r
+  If Buffer is NULL, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The number of bytes written.\r
+\r
+**/\r
 UINTN\r
 EFIAPI\r
 SmBusWriteBlock (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     VOID                      *Buffer,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  OUT VOID           *Buffer,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffffe | MAX_BIT)) == 0);\r
-  return SmBusBlock (\r
-           SmBusAddress | B_SMBUS_WRITE,\r
-           B_SMB_CMD_BLOCK,\r
+  ASSERT (Buffer != NULL);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusBlock (\r
+           SMBUS_V_SMB_CMD_BLOCK,\r
+           SmBusAddress | SMBUS_B_WRITE,\r
            Buffer,\r
            NULL,\r
            Status\r
            );\r
 }\r
 \r
+/**\r
+  Executes an SMBUS block process call command.\r
+\r
+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.\r
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
+  Bytes are written to the SMBUS from OutBuffer.  Bytes are then read from the SMBUS into InBuffer.\r
+  If Status is not NULL, then the status of the executed command is returned in Status.\r
+  It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.\r
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
+  If OutBuffer is NULL, then ASSERT().\r
+  If InBuffer is NULL, then ASSERT().\r
+  If any reserved bits of SmBusAddress are set, then ASSERT().\r
+\r
+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
+                          SMBUS Command, SMBUS Data Length, and PEC.\r
+  @param  OutBuffer       Pointer to the buffer of bytes to write to the SMBUS.\r
+  @param  InBuffer        Pointer to the buffer of bytes to read from the SMBUS.\r
+  @param  Status          Return status for the executed command.\r
+                          This is an optional parameter and may be NULL.\r
+\r
+  @return The number of bytes written.\r
+\r
+**/\r
 UINTN\r
 EFIAPI\r
 SmBusBlockProcessCall (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      VOID                      *OutBuffer,\r
-  OUT     VOID                      *InBuffer,\r
-  OUT     RETURN_STATUS             *Status\r
+  IN  UINTN          SmBusAddress,\r
+  IN  VOID           *OutBuffer,\r
+  OUT VOID           *InBuffer,\r
+  OUT RETURN_STATUS  *Status        OPTIONAL\r
   )\r
 {\r
-  ASSERT ((SmBusAddress & ~(0xfffffe | MAX_BIT)) == 0);\r
-  return SmBusBlock (\r
-           SmBusAddress | B_SMBUS_WRITE,\r
-           B_SMB_CMD_BLOCK_PROCESS,\r
+  ASSERT (InBuffer  != NULL);\r
+  ASSERT (OutBuffer != NULL);\r
+  ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
+\r
+  return InternalSmBusBlock (\r
+           SMBUS_V_SMB_CMD_BLOCK_PROCESS,\r
+           SmBusAddress | SMBUS_B_WRITE,\r
            OutBuffer,\r
            InBuffer,\r
            Status\r
            );\r
 }\r
-\r
-RETURN_STATUS\r
-EFIAPI\r
-SmBusArpAll (\r
-  IN      UINTN                     SmBusAddress\r
-  );\r
-\r
-RETURN_STATUS\r
-EFIAPI\r
-SmBusArpDevice (\r
-  IN      UINTN                     SmBusAddress,\r
-  IN      CONST GUID                *Uuid\r
-  );\r
-\r
-RETURN_STATUS\r
-EFIAPI\r
-SmBusGetUuid (\r
-  IN      UINTN                     SmBusAddress,\r
-  OUT     GUID                      *Uuid\r
-  );\r
diff --git a/MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h b/MdePkg/Library/BaseSmbusLib/SmbusLibRegisters.h
new file mode 100644 (file)
index 0000000..6eb14fa
--- /dev/null
@@ -0,0 +1,120 @@
+/** @file\r
+  Base SMBUS library implementation built upon I/O library.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  Module Name:  SmbusLib.h\r
+\r
+**/\r
+\r
+#ifndef __SMBUS_LIB_REGISTER_H\r
+#define __SMBUS_LIB_REGISTER_H\r
+\r
+#define SMBUS_R_HST_STS               0x00  // Host Status Register\r
+#define SMBUS_B_HOST_BUSY             0x01  // RO\r
+#define SMBUS_B_INTR                  0x02  // R/WC\r
+#define SMBUS_B_DEV_ERR               0x04  // R/WC\r
+#define SMBUS_B_BUS_ERR               0x08  // R/WC\r
+#define SMBUS_B_FAILED                0x10  // R/WC\r
+#define SMBUS_B_SMBALERT_STS          0x20  // R/WC\r
+#define SMBUS_B_INUSE_STS             0x40  // R/WC\r
+#define SMBUS_B_BYTE_DONE_STS         0x80  // R/WC\r
+#define SMBUS_B_ERROR                 (SMBUS_B_DEV_ERR | SMBUS_B_BUS_ERR | SMBUS_B_FAILED)\r
+#define SMBUS_B_HSTS_ALL              0xFF  // R/WC\r
+\r
+\r
+#define SMBUS_R_HST_CTL               0x02  // Host Control Register R/W\r
+#define SMBUS_B_INTREN                0x01  // RW\r
+#define SMBUS_B_KILL                  0x02  // RW\r
+#define SMBUS_B_CMD                   (7 << 2) // RW\r
+#define SMBUS_V_SMB_CMD_QUICK         (0 << 2)\r
+#define SMBUS_V_SMB_CMD_BYTE          (1 << 2)\r
+#define SMBUS_V_SMB_CMD_BYTE_DATA     (2 << 2)\r
+#define SMBUS_V_SMB_CMD_WORD_DATA     (3 << 2)\r
+#define SMBUS_V_SMB_CMD_PROCESS_CALL  (4 << 2)\r
+#define SMBUS_V_SMB_CMD_BLOCK         (5 << 2)\r
+#define SMBUS_V_SMB_CMD_IIC_READ      (6 << 2)\r
+#define SMBUS_V_SMB_CMD_BLOCK_PROCESS (7 << 2)\r
+#define SMBUS_B_LAST_BYTE             0x20  // WO\r
+#define SMBUS_B_START                 0x40  // WO\r
+#define SMBUS_B_PEC_EN                0x80  // RW\r
+\r
+\r
+#define SMBUS_R_HST_CMD               0x03  // Host Command Register R/W\r
+\r
+\r
+#define SMBUS_R_XMIT_SLVA             0x04  // Transmit Slave Address Register R/W\r
+#define SMBUS_B_RW                    0x01  // RW\r
+#define SMBUS_B_READ                  0x01  // RW\r
+#define SMBUS_B_WRITE                 0x00  // RW\r
+#define SMBUS_B_ADDRESS               0xFE  // RW\r
+\r
+\r
+#define SMBUS_R_HST_D0                0x05  // Data 0 Register R/W\r
+\r
+\r
+#define SMBUS_R_HST_D1                0x06  // Data 1 Register R/W\r
+\r
+\r
+#define SMBUS_R_HOST_BLOCK_DB         0x07  // Host Block Data Register R/W\r
+\r
+\r
+#define SMBUS_R_PEC                   0x08  // Packet Error Check Data Register R/W\r
+\r
+\r
+#define SMBUS_R_RCV_SLVA              0x09  // Receive Slave Address Register R/W\r
+#define SMBUS_B_SLAVE_ADDR            0x7F  // RW\r
+\r
+\r
+#define SMBUS_R_SLV_DATA              0x0A  // Receive Slave Data Register R/W\r
+\r
+\r
+#define SMBUS_R_AUX_STS               0x0C  // Auxiliary Status Register R/WC\r
+#define SMBUS_B_CRCE                  0x01  // R/WC\r
+\r
+\r
+#define SMBUS_R_AUX_CTL               0x0D  // Auxiliary Control Register R/W\r
+#define SMBUS_B_AAC                   0x01  // R/W\r
+#define SMBUS_B_E32B                  0x02  // R/W\r
+\r
+\r
+#define SMBUS_R_SMLINK_PIN_CTL        0x0E  // SMLINK Pin Control Register R/W\r
+#define SMBUS_B_SMLINK0_CUR_STS       0x01  // RO\r
+#define SMBUS_B_SMLINK1_CUR_STS       0x02  // RO\r
+#define SMBUS_B_SMLINK_CLK_CTL        0x04  // RW\r
+\r
+\r
+#define SMBUS_R_SMBUS_PIN_CTL         0x0F  // SMBus Pin Control Register R/W\r
+#define SMBUS_B_SMBCLK_CUR_STS        0x01  // RO\r
+#define SMBUS_B_SMBDATA_CUR_STS       0x02  // RO\r
+#define SMBUS_B_SMBCLK_CTL            0x04  // RW\r
+\r
+\r
+#define SMBUS_R_SLV_STS               0x10  // Slave Status Register R/WC\r
+#define SMBUS_B_HOST_NOTIFY_STS       0x01  // R/WC\r
+\r
+\r
+#define SMBUS_R_SLV_CMD               0x11  // Slave Command Register R/W\r
+#define SMBUS_B_HOST_NOTIFY_INTREN    0x01  // R/W\r
+#define SMBUS_B_HOST_NOTIFY_WKEN      0x02  // R/W\r
+#define SMBUS_B_SMBALERT_DIS          0x04  // R/W\r
+\r
+\r
+#define SMBUS_R_NOTIFY_DADDR          0x14  // Notify Device Address Register RO\r
+#define SMBUS_B_DEVICE_ADDRESS        0xFE  // RO\r
+\r
+\r
+#define SMBUS_R_NOTIFY_DLOW           0x16  // Notify Data Low Byte Register RO\r
+\r
+\r
+#define SMBUS_R_NOTIFY_DHIGH          0x17  // Notify Data High Byte Register RO   \r
+\r
+\r
+#endif\r
index febd1e4..45336c5 100644 (file)
 \r
 extern VOID *gHobList;\r
 \r
+\r
 /**\r
   Returns the pointer to the HOB list.\r
 \r
+  This function returns the pointer to first HOB in the list.\r
+\r
   @return The pointer to the HOB list.\r
 \r
 **/\r
@@ -34,11 +37,17 @@ GetHobList (
 }\r
 \r
 /**\r
+  Returns the next instance of a HOB type from the starting HOB.\r
+\r
   This function searches the first instance of a HOB type from the starting HOB pointer. \r
-  If there does not exist such HOB type from the starting HOB pointer, it will return NULL. \r
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Type The HOB type to return.\r
-  @param  HobStart The starting HOB pointer to search from.\r
+  @param  Type          The HOB type to return.\r
+  @param  HobStart      The starting HOB pointer to search from.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -56,7 +65,7 @@ GetNextHob (
    \r
   Hob.Raw = (UINT8 *) HobStart;\r
   //\r
-  // Parse the HOB list, stop if end of list or matching type found.\r
+  // Parse the HOB list until end of list or matching type is found.\r
   //\r
   while (!END_OF_HOB_LIST (Hob)) {\r
     if (Hob.Header->HobType == Type) {\r
@@ -68,10 +77,12 @@ GetNextHob (
 }\r
 \r
 /**\r
+  Returns the first instance of a HOB type among the whole HOB list.\r
+\r
   This function searches the first instance of a HOB type among the whole HOB list. \r
   If there does not exist such HOB type in the HOB list, it will return NULL. \r
 \r
-  @param  Type The HOB type to return.\r
+  @param  Type          The HOB type to return.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -93,9 +104,16 @@ GetFirstHob (
   Such HOB should satisfy two conditions: \r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If Guid is NULL, then ASSERT().\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
-  @param  HobStart A pointer to a Guid.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+  @param  HobStart      A pointer to a Guid.\r
 \r
   @return The next instance of the matched GUID HOB from the starting HOB.\r
 \r
@@ -124,8 +142,11 @@ GetNextGuidHob (
   Such HOB should satisfy two conditions:\r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  If Guid is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
 \r
   @return The first instance of the matched GUID HOB among the whole HOB list.\r
 \r
@@ -143,12 +164,18 @@ GetFirstGuidHob (
 }\r
 \r
 /**\r
+  Builds a HOB for a loaded PE32 module.\r
+\r
   This function builds a HOB for a loaded PE32 module.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If ModuleName is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-  @param  ModuleName The GUID File Name of the module.\r
-  @param  MemoryAllocationModule The 64 bit physical address of the module.\r
-  @param  ModuleLength The length of the module in bytes.\r
-  @param  EntryPoint The 64 bit physical address of the module\92s entry point.\r
+  @param  ModuleName              The GUID File Name of the module.\r
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.\r
+  @param  ModuleLength            The length of the module in bytes.\r
+  @param  EntryPoint              The 64 bit physical address of the module\92s entry point.\r
 \r
 **/\r
 VOID\r
@@ -169,10 +196,15 @@ BuildModuleHob (
 /**\r
   Builds a HOB that describes a chunk of system memory.\r
 \r
-  @param  ResourceType The type of resource described by this HOB.\r
-  @param  ResourceAttribute The resource attributes of the memory described by this HOB.\r
-  @param  PhysicalStart The 64 bit physical address of memory described by this HOB.\r
-  @param  NumberOfBytes The length of the memory described by this HOB in bytes.\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
 \r
 **/\r
 VOID\r
@@ -191,11 +223,19 @@ BuildResourceDescriptorHob (
 }\r
 \r
 /**\r
+  Builds a GUID HOB with a certain data length.\r
+\r
   This function builds a customized HOB tagged with a GUID for identification \r
   and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
 \r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -215,12 +255,21 @@ BuildGuidHob (
 }\r
 \r
 /**\r
-  This function builds a customized HOB tagged with a GUID for identification, \r
-  copies the input data to the HOB data field, and returns the start address of GUID HOB data.\r
-\r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  Data The data to be copied into the data field of the GUID HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  Copies a data buffer to a newly-built HOB.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification,\r
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If Data is NULL and DataLength > 0, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
+\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  Data          The data to be copied into the data field of the GUID HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -243,8 +292,13 @@ BuildGuidDataHob (
 /**\r
   Builds a Firmware Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Firmware Volume.\r
-  @param  Length The size of the Firmware Volume in bytes.\r
+  This function builds a Firmware Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -263,8 +317,13 @@ BuildFvHob (
 /**\r
   Builds a Capsule Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Capsule Volume.\r
-  @param  Length The size of the Capsule Volume in bytes.\r
+  This function builds a Capsule Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Capsule Volume.\r
+  @param  Length        The size of the Capsule Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -283,8 +342,13 @@ BuildCvHob (
 /**\r
   Builds a HOB for the CPU.\r
 \r
-  @param  SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
-  @param  SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
+  This function builds a HOB for the CPU.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.\r
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.\r
 \r
 **/\r
 VOID\r
@@ -303,8 +367,13 @@ BuildCpuHob (
 /**\r
   Builds a HOB for the Stack.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the Stack.\r
-  @param  Length The length of the stack in bytes.\r
+  This function builds a HOB for the stack.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
 \r
 **/\r
 VOID\r
@@ -323,9 +392,14 @@ BuildStackHob (
 /**\r
   Builds a HOB for the BSP store.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the BSP.\r
-  @param  Length The length of the BSP store in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for BSP store.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the BSP.\r
+  @param  Length        The length of the BSP store in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
@@ -345,9 +419,14 @@ BuildBspStoreHob (
 /**\r
   Builds a HOB for the memory allocation.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the memory.\r
-  @param  Length The length of the memory allocation in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for the memory allocation.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the memory.\r
+  @param  Length        The length of the memory allocation in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
index a914dd7..41baba2 100644 (file)
@@ -48,9 +48,9 @@ HobLibConstructor (
 /**\r
   Returns the pointer to the HOB list.\r
 \r
-  None.\r
+  This function returns the pointer to first HOB in the list.\r
 \r
-  The pointer to the HOB list.\r
+  @return The pointer to the HOB list.\r
 \r
 **/\r
 VOID *\r
@@ -63,11 +63,17 @@ GetHobList (
 }\r
 \r
 /**\r
+  Returns the next instance of a HOB type from the starting HOB.\r
+\r
   This function searches the first instance of a HOB type from the starting HOB pointer. \r
-  If there does not exist such HOB type from the starting HOB pointer, it will return NULL. \r
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Type The HOB type to return.\r
-  @param  HobStart The starting HOB pointer to search from.\r
+  @param  Type          The HOB type to return.\r
+  @param  HobStart      The starting HOB pointer to search from.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -85,7 +91,7 @@ GetNextHob (
    \r
   Hob.Raw = (UINT8 *) HobStart;\r
   //\r
-  // Parse the HOB list, stop if end of list or matching type found.\r
+  // Parse the HOB list until end of list or matching type is found.\r
   //\r
   while (!END_OF_HOB_LIST (Hob)) {\r
     if (Hob.Header->HobType == Type) {\r
@@ -97,10 +103,12 @@ GetNextHob (
 }\r
 \r
 /**\r
+  Returns the first instance of a HOB type among the whole HOB list.\r
+\r
   This function searches the first instance of a HOB type among the whole HOB list. \r
   If there does not exist such HOB type in the HOB list, it will return NULL. \r
 \r
-  @param  Type The HOB type to return.\r
+  @param  Type          The HOB type to return.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -122,9 +130,16 @@ GetFirstHob (
   Such HOB should satisfy two conditions: \r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If Guid is NULL, then ASSERT().\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
-  @param  HobStart A pointer to a Guid.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+  @param  HobStart      A pointer to a Guid.\r
 \r
   @return The next instance of the matched GUID HOB from the starting HOB.\r
 \r
@@ -153,8 +168,11 @@ GetNextGuidHob (
   Such HOB should satisfy two conditions:\r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  If Guid is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
 \r
   @return The first instance of the matched GUID HOB among the whole HOB list.\r
 \r
@@ -172,12 +190,18 @@ GetFirstGuidHob (
 }\r
 \r
 /**\r
+  Builds a HOB for a loaded PE32 module.\r
+\r
   This function builds a HOB for a loaded PE32 module.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If ModuleName is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-  @param  ModuleName The GUID File Name of the module.\r
-  @param  MemoryAllocationModule The 64 bit physical address of the module.\r
-  @param  ModuleLength The length of the module in bytes.\r
-  @param  EntryPoint The 64 bit physical address of the module\92s entry point.\r
+  @param  ModuleName              The GUID File Name of the module.\r
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.\r
+  @param  ModuleLength            The length of the module in bytes.\r
+  @param  EntryPoint              The 64 bit physical address of the module\92s entry point.\r
 \r
 **/\r
 VOID\r
@@ -198,10 +222,15 @@ BuildModuleHob (
 /**\r
   Builds a HOB that describes a chunk of system memory.\r
 \r
-  @param  ResourceType The type of resource described by this HOB.\r
-  @param  ResourceAttribute The resource attributes of the memory described by this HOB.\r
-  @param  PhysicalStart The 64 bit physical address of memory described by this HOB.\r
-  @param  NumberOfBytes The length of the memory described by this HOB in bytes.\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
 \r
 **/\r
 VOID\r
@@ -220,11 +249,19 @@ BuildResourceDescriptorHob (
 }\r
 \r
 /**\r
+  Builds a GUID HOB with a certain data length.\r
+\r
   This function builds a customized HOB tagged with a GUID for identification \r
   and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
 \r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -244,12 +281,21 @@ BuildGuidHob (
 }\r
 \r
 /**\r
-  This function builds a customized HOB tagged with a GUID for identification, \r
-  copies the input data to the HOB data field, and returns the start address of GUID HOB data.\r
-\r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  Data The data to be copied into the data field of the GUID HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  Copies a data buffer to a newly-built HOB.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification,\r
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If Data is NULL and DataLength > 0, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
+\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  Data          The data to be copied into the data field of the GUID HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -272,8 +318,13 @@ BuildGuidDataHob (
 /**\r
   Builds a Firmware Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Firmware Volume.\r
-  @param  Length The size of the Firmware Volume in bytes.\r
+  This function builds a Firmware Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -292,8 +343,13 @@ BuildFvHob (
 /**\r
   Builds a Capsule Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Capsule Volume.\r
-  @param  Length The size of the Capsule Volume in bytes.\r
+  This function builds a Capsule Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Capsule Volume.\r
+  @param  Length        The size of the Capsule Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -312,8 +368,13 @@ BuildCvHob (
 /**\r
   Builds a HOB for the CPU.\r
 \r
-  @param  SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
-  @param  SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
+  This function builds a HOB for the CPU.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.\r
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.\r
 \r
 **/\r
 VOID\r
@@ -332,8 +393,13 @@ BuildCpuHob (
 /**\r
   Builds a HOB for the Stack.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the Stack.\r
-  @param  Length The length of the stack in bytes.\r
+  This function builds a HOB for the stack.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
 \r
 **/\r
 VOID\r
@@ -352,9 +418,14 @@ BuildStackHob (
 /**\r
   Builds a HOB for the BSP store.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the BSP.\r
-  @param  Length The length of the BSP store in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for BSP store.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the BSP.\r
+  @param  Length        The length of the BSP store in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
@@ -374,9 +445,14 @@ BuildBspStoreHob (
 /**\r
   Builds a HOB for the memory allocation.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the memory.\r
-  @param  Length The length of the memory allocation in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for the memory allocation.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the memory.\r
+  @param  Length        The length of the memory allocation in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
index a06f169..380a735 100644 (file)
@@ -19,9 +19,9 @@
 /**\r
   Returns the pointer to the HOB list.\r
 \r
-  None.\r
+  This function returns the pointer to first HOB in the list.\r
 \r
-  The pointer to the HOB list.\r
+  @return The pointer to the HOB list.\r
 \r
 **/\r
 VOID *\r
@@ -41,11 +41,17 @@ GetHobList (
 }\r
 \r
 /**\r
+  Returns the next instance of a HOB type from the starting HOB.\r
+\r
   This function searches the first instance of a HOB type from the starting HOB pointer. \r
-  If there does not exist such HOB type from the starting HOB pointer, it will return NULL. \r
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Type The HOB type to return.\r
-  @param  HobStart The starting HOB pointer to search from.\r
+  @param  Type          The HOB type to return.\r
+  @param  HobStart      The starting HOB pointer to search from.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -63,7 +69,7 @@ GetNextHob (
    \r
   Hob.Raw = (UINT8 *) HobStart;\r
   //\r
-  // Parse the HOB list, stop if end of list or matching type found.\r
+  // Parse the HOB list until end of list or matching type is found.\r
   //\r
   while (!END_OF_HOB_LIST (Hob)) {\r
     if (Hob.Header->HobType == Type) {\r
@@ -75,10 +81,12 @@ GetNextHob (
 }\r
 \r
 /**\r
+  Returns the first instance of a HOB type among the whole HOB list.\r
+\r
   This function searches the first instance of a HOB type among the whole HOB list. \r
   If there does not exist such HOB type in the HOB list, it will return NULL. \r
 \r
-  @param  Type The HOB type to return.\r
+  @param  Type          The HOB type to return.\r
 \r
   @return The next instance of a HOB type from the starting HOB.\r
 \r
@@ -100,9 +108,16 @@ GetFirstHob (
   Such HOB should satisfy two conditions: \r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If Guid is NULL, then ASSERT().\r
+  If HobStart is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
-  @param  HobStart A pointer to a Guid.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+  @param  HobStart      A pointer to a Guid.\r
 \r
   @return The next instance of the matched GUID HOB from the starting HOB.\r
 \r
@@ -131,8 +146,11 @@ GetNextGuidHob (
   Such HOB should satisfy two conditions:\r
   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
   If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  If Guid is NULL, then ASSERT().\r
 \r
-  @param  Guid The GUID to match with in the HOB list.\r
+  @param  Guid          The GUID to match with in the HOB list.\r
 \r
   @return The first instance of the matched GUID HOB among the whole HOB list.\r
 \r
@@ -150,10 +168,12 @@ GetFirstGuidHob (
 }\r
 \r
 /**\r
-  Add a new HOB to the HOB List.\r
+  Adds a new HOB to the HOB List.\r
 \r
-  @param  Type Type of the new HOB.\r
-  @param  Length Length of the new HOB to allocate.\r
+  This internal function enables PEIMs to create various types of HOBs.\r
+\r
+  @param  Type          Type of the new HOB.\r
+  @param  Length        Length of the new HOB to allocate.\r
 \r
   @return The address of new HOB.\r
 \r
@@ -176,12 +196,18 @@ InternalPeiCreateHob (
 }\r
 \r
 /**\r
+  Builds a HOB for a loaded PE32 module.\r
+\r
   This function builds a HOB for a loaded PE32 module.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If ModuleName is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
 \r
-  @param  ModuleName The GUID File Name of the module.\r
-  @param  MemoryAllocationModule The 64 bit physical address of the module.\r
-  @param  ModuleLength The length of the module in bytes.\r
-  @param  EntryPoint The 64 bit physical address of the module\92s entry point.\r
+  @param  ModuleName              The GUID File Name of the module.\r
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.\r
+  @param  ModuleLength            The length of the module in bytes.\r
+  @param  EntryPoint              The 64 bit physical address of the module\92s entry point.\r
 \r
 **/\r
 VOID\r
@@ -209,10 +235,15 @@ BuildModuleHob (
 /**\r
   Builds a HOB that describes a chunk of system memory.\r
 \r
-  @param  ResourceType The type of resource described by this HOB.\r
-  @param  ResourceAttribute The resource attributes of the memory described by this HOB.\r
-  @param  PhysicalStart The 64 bit physical address of memory described by this HOB.\r
-  @param  NumberOfBytes The length of the memory described by this HOB in bytes.\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
 \r
 **/\r
 VOID\r
@@ -235,11 +266,19 @@ BuildResourceDescriptorHob (
 }\r
 \r
 /**\r
-  This function builds a customized HOB tagged with a GUID for identification\r
-  and returns the start address of GUID HOB data so that caller can fill the customized data.\r
+  Builds a GUID HOB with a certain data length.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification \r
+  and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
 \r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -264,12 +303,21 @@ BuildGuidHob (
 }\r
 \r
 /**\r
-  This function builds a customized HOB tagged with a GUID for identification,\r
-  copies the input data to the HOB data field, and returns the start address of GUID HOB data.\r
+  Copies a data buffer to a newly-built HOB.\r
 \r
-  @param  Guid The GUID to tag the customized HOB.\r
-  @param  Data The data to be copied into the data field of the GUID HOB.\r
-  @param  DataLength The size of the data payload for the GUID HOB.\r
+  This function builds a customized HOB tagged with a GUID for identification,\r
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If Data is NULL and DataLength > 0, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength > (0x10000 - sizeof (EFI_HOB_TYPE_GUID)), then ASSERT().\r
+\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  Data          The data to be copied into the data field of the GUID HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
   @return The start address of GUID HOB data.\r
 \r
@@ -292,8 +340,13 @@ BuildGuidDataHob (
 /**\r
   Builds a Firmware Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Firmware Volume.\r
-  @param  Length The size of the Firmware Volume in bytes.\r
+  This function builds a Firmware Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -314,8 +367,13 @@ BuildFvHob (
 /**\r
   Builds a Capsule Volume HOB.\r
 \r
-  @param  BaseAddress The base address of the Capsule Volume.\r
-  @param  Length The size of the Capsule Volume in bytes.\r
+  This function builds a Capsule Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Capsule Volume.\r
+  @param  Length        The size of the Capsule Volume in bytes.\r
 \r
 **/\r
 VOID\r
@@ -336,8 +394,13 @@ BuildCvHob (
 /**\r
   Builds a HOB for the CPU.\r
 \r
-  @param  SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
-  @param  SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
+  This function builds a HOB for the CPU.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.\r
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.\r
 \r
 **/\r
 VOID\r
@@ -358,8 +421,13 @@ BuildCpuHob (
 /**\r
   Builds a HOB for the Stack.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the Stack.\r
-  @param  Length The length of the stack in bytes.\r
+  This function builds a HOB for the stack.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
 \r
 **/\r
 VOID\r
@@ -382,9 +450,14 @@ BuildStackHob (
 /**\r
   Builds a HOB for the BSP store.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the BSP.\r
-  @param  Length The length of the BSP store in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for BSP store.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the BSP.\r
+  @param  Length        The length of the BSP store in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
@@ -408,9 +481,14 @@ BuildBspStoreHob (
 /**\r
   Builds a HOB for the memory allocation.\r
 \r
-  @param  BaseAddress The 64 bit physical address of the memory.\r
-  @param  Length The length of the memory allocation in bytes.\r
-  @param  MemoryType Type of memory allocated by this HOB.\r
+  This function builds a HOB for the memory allocation.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the memory.\r
+  @param  Length        The length of the memory allocation in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
 \r
 **/\r
 VOID\r
index 8dc84f4..1b1376e 100644 (file)
@@ -155,9 +155,9 @@ AppendDevicePath (
   This function appends the device path node SecondDevicePath\r
   to every device path instance in FirstDevicePath.\r
 \r
-  @param  FirstDevicePath A pointer to a device path data structure.\r
+  @param  DevicePath A pointer to a device path data structure.\r
   \r
-  @param  SecondDevicePath A pointer to a single device path node.\r
+  @param  DevicePathNode A pointer to a single device path node.\r
 \r
   @return A pointer to the new device path.\r
   If there is not enough temporary pool memory available to complete this function,\r
@@ -167,40 +167,37 @@ AppendDevicePath (
 EFI_DEVICE_PATH_PROTOCOL *\r
 EFIAPI\r
 AppendDevicePathNode (\r
-  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,\r
-  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode\r
   )\r
 {\r
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *NextNode;\r
   EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;\r
   UINTN                     NodeLength;\r
-  UINTN                     Size1;\r
 \r
   //\r
   // Build a Node that has a terminator on it\r
   //\r
-  NodeLength  = DevicePathNodeLength (SecondDevicePath);\r
-  Size1       = GetDevicePathSize (FirstDevicePath);\r
-  \r
-  NewDevicePath = AllocatePool (NodeLength + Size1);\r
-  if (NewDevicePath != NULL) {\r
-    //\r
-    // Copy the first device path to the new device path\r
-    //\r
-    NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);\r
-\r
-    //\r
-    // Copy the device path node to the new device path\r
-    //\r
-    NextNode      = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));\r
-    NextNode      = CopyMem (NextNode, SecondDevicePath, NodeLength);\r
+  NodeLength = DevicePathNodeLength (DevicePathNode);\r
 \r
-    //\r
-    // Terminate the whole device path\r
-    //\r
-    NextNode      = NextDevicePathNode (NextNode);\r
-    SetDevicePathEndNode (NextNode);\r
+  TempDevicePath = AllocatePool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
+  if (TempDevicePath == NULL) {\r
+    return NULL;\r
   }\r
+  TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);\r
+  //\r
+  // Add and end device path node to convert Node to device path\r
+  //\r
+  NextNode = NextDevicePathNode (TempDevicePath);\r
+  SetDevicePathEndNode (NextNode);\r
+  //\r
+  // Append device paths\r
+  //\r
+  NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);\r
+\r
+  FreePool (TempDevicePath);\r
+\r
   return NewDevicePath;\r
 }\r
 \r