]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. PI SMBIOS Checkin. Major change include:
authordavidhuang <davidhuang@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 Nov 2009 04:01:32 +0000 (04:01 +0000)
committerdavidhuang <davidhuang@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 Nov 2009 04:01:32 +0000 (04:01 +0000)
1) Produce PI SMBIOS protocol in MdeModulePkg
2) Update all consumers (in CorePkgs and native platform pkgs) to consume SMBIOS protocol instead of DataHub
3) Pass ECC tool; Verify Nt32, Duet, Unix platform

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

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c [new file with mode: 0644]
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h [new file with mode: 0644]
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf [new file with mode: 0644]

index 0a9fb454c9330bce1d050ad2009039569bdd41ed..e76738723080afa77608c06adc7f2d947ff8751e 100644 (file)
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
   MdeModulePkg/Universal/Metronome/Metronome.inf\r
   MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf\r
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf\r
 \r
   MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf\r
   MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf\r
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c
new file mode 100644 (file)
index 0000000..03b8b24
--- /dev/null
@@ -0,0 +1,1034 @@
+/** @file\r
+  This code produces the Smbios protocol. It also responsible for constructing \r
+  SMBIOS table into system table.\r
+  \r
+Copyright (c) 2009, Intel Corporation                                                         \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
+**/\r
+\r
+#include "SmbiosDxe.h"\r
+\r
+//\r
+// Module Global:\r
+// Since this driver will only ever produce one instance of the\r
+// protocol you are not required to dynamically allocate the PrivateData.\r
+//\r
+SMBIOS_INSTANCE mPrivateData;\r
+\r
+//\r
+// Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.\r
+//\r
+SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure    = NULL;\r
+SMBIOS_TABLE_ENTRY_POINT EntryPointStructureData = {\r
+  //\r
+  // AnchorString\r
+  //\r
+  {\r
+    0x5f,\r
+    0x53,\r
+    0x4d,\r
+    0x5f\r
+  },\r
+  //\r
+  // EntryPointStructureChecksum,TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // EntryPointStructure Length\r
+  //\r
+  0x1f,\r
+  //\r
+  // MajorVersion: 2 (Version 2.4)\r
+  //\r
+  0x02,\r
+  //\r
+  // MinorVersion: 4 (Version 2.4)\r
+  //\r
+  0x04,\r
+  //\r
+  // MaxStructureSize, TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // EntryPointRevision\r
+  //\r
+  0,\r
+  //\r
+  // FormattedArea\r
+  //\r
+  {\r
+    0,\r
+    0,\r
+    0,\r
+    0,\r
+    0\r
+  },\r
+  //\r
+  // IntermediateAnchorString\r
+  //\r
+  {\r
+    0x5f,\r
+    0x44,\r
+    0x4d,\r
+    0x49,\r
+    0x5f\r
+  },\r
+  //\r
+  // IntermediateChecksum, TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // StructureTableLength, TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // StructureTableAddress, TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // NumberOfSmbiosStructures, TO BE FILLED\r
+  //\r
+  0,\r
+  //\r
+  // SmbiosBcdRevision\r
+  //\r
+  0  \r
+};\r
+\r
+\r
+/**\r
+\r
+  Get the full size of smbios structure including optional strings that follow the formatted structure.\r
+\r
+  @param Head                   Pointer to the beginning of smbios structure.\r
+  @param Size                   The returned size.\r
+  @param NumberOfStrings        The returned number of optional strings that follow the formatted structure.\r
+\r
+  @retval EFI_SUCCESS           Size retured in Size.\r
+  @retval EFI_INVALID_PARAMETER Input smbios structure mal-formed or Size is NULL.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetSmbiosStructureSize (\r
+  IN   EFI_SMBIOS_TABLE_HEADER          *Head,\r
+  OUT  UINTN                            *Size,\r
+  OUT  UINTN                            *NumberOfStrings\r
+  )\r
+{\r
+  UINTN  FullSize;\r
+  UINT8  StrLen;\r
+  INT8*  CharInStr;\r
+  \r
+  if (Size == NULL || NumberOfStrings == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  FullSize = Head->Length;\r
+  CharInStr = (INT8*)Head + Head->Length;\r
+  *Size = FullSize;\r
+  *NumberOfStrings = 0;\r
+  StrLen = 0;\r
+  //\r
+  // look for the two consecutive zeros, check the string limit by the way.\r
+  //\r
+  while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
+    if (*CharInStr == 0) {\r
+      *NumberOfStrings += 1;\r
+      *Size += 1;\r
+      CharInStr++;\r
+    }\r
+\r
+    for (StrLen = 0 ; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {\r
+      if (*(CharInStr+StrLen) == 0) {\r
+        break;\r
+      }  \r
+    }\r
+\r
+    if (StrLen == SMBIOS_STRING_MAX_LENGTH) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // forward the pointer\r
+    //\r
+    CharInStr += StrLen;\r
+    *Size += StrLen;\r
+    \r
+  }\r
+\r
+  if (*NumberOfStrings > 0) {\r
+    *NumberOfStrings += 1;\r
+  }\r
+  //\r
+  // count ending two zeros.\r
+  //\r
+  *Size += 2;\r
+  return EFI_SUCCESS;  \r
+}\r
+\r
+/**\r
+\r
+  Determin whether an SmbiosHandle has already in use.\r
+\r
+  @param Head        Pointer to the beginning of smbios structure.\r
+  @param Handle      A unique handle will be assigned to the SMBIOS record.\r
+\r
+  @retval TRUE       Smbios handle already in use.\r
+  @retval FALSE      Smbios handle is NOT used.\r
+  \r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckSmbiosHandleExistance (\r
+  IN  LIST_ENTRY           *Head,\r
+  IN  EFI_SMBIOS_HANDLE    Handle\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  SMBIOS_HANDLE_ENTRY     *HandleEntry;\r
+  \r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    HandleEntry = SMBIOS_HANDLE_ENTRY_FROM_LINK(Link);\r
+    if (HandleEntry->SmbiosHandle == Handle) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+\r
+  Get the max SmbiosHandle that could be use.\r
+\r
+  @param  This           The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  MaxHandle      The max handle that could be assigned to the SMBIOS record.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+GetMaxSmbiosHandle (\r
+  IN CONST  EFI_SMBIOS_PROTOCOL   *This,\r
+  IN OUT    EFI_SMBIOS_HANDLE     *MaxHandle\r
+  ) \r
+{\r
+  if (This->MajorVersion == 2 && This->MinorVersion == 0) {\r
+    *MaxHandle = 0xFFFE;\r
+  } else {\r
+    *MaxHandle = 0xFEFF;\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Get an SmbiosHandle that could use.\r
+\r
+  @param  This                   The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  SmbiosHandle           A unique handle will be assigned to the SMBIOS record.\r
+\r
+  @retval EFI_SUCCESS            Smbios handle got.\r
+  @retval EFI_OUT_OF_RESOURCES   Smbios handle is NOT available.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetAvailableSmbiosHandle (\r
+  IN CONST EFI_SMBIOS_PROTOCOL   *This,\r
+  IN OUT   EFI_SMBIOS_HANDLE     *Handle\r
+  )\r
+{\r
+  LIST_ENTRY              *Head;\r
+  SMBIOS_INSTANCE         *Private;\r
+  EFI_SMBIOS_HANDLE       MaxSmbiosHandle;\r
+  EFI_SMBIOS_HANDLE       AvailableHandle;\r
+\r
+  GetMaxSmbiosHandle(This, &MaxSmbiosHandle);\r
+\r
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  Head = &Private->AllocatedHandleListHead;\r
+  for (AvailableHandle = 1; AvailableHandle < MaxSmbiosHandle; AvailableHandle++) {\r
+    if (!CheckSmbiosHandleExistance(Head, AvailableHandle)) {\r
+      *Handle = AvailableHandle;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_OUT_OF_RESOURCES;\r
+}\r
+\r
+\r
+/**\r
+  Add an SMBIOS record.\r
+\r
+  @param  This                  The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  ProducerHandle        The handle of the controller or driver associated with the SMBIOS information. NULL\r
+                                means no handle.\r
+  @param  SmbiosHandle          On entry, if non-zero, the handle of the SMBIOS record. If zero, then a unique handle\r
+                                will be assigned to the SMBIOS record. If the SMBIOS handle is already in use\r
+                                EFI_ALREADY_STARTED is returned and the SMBIOS record is not updated.\r
+  @param  Record                The data for the fixed portion of the SMBIOS record. The format of the record is\r
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined \r
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or \r
+                                a set of null terminated strings and a null.\r
+\r
+  @retval EFI_SUCCESS           Record was added.\r
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.\r
+  @retval EFI_ALREADY_STARTED   The SmbiosHandle passed in was already in use.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosAdd (\r
+  IN CONST EFI_SMBIOS_PROTOCOL  *This,\r
+  IN EFI_HANDLE                 ProducerHandle, OPTIONAL\r
+  IN OUT EFI_SMBIOS_HANDLE      *SmbiosHandle,\r
+  IN EFI_SMBIOS_TABLE_HEADER    *Record\r
+  )\r
+{\r
+  VOID                        *Raw;\r
+  UINTN                       TotalSize;\r
+  UINTN                       RecordSize;\r
+  UINTN                       StructureSize;\r
+  UINTN                       NumberOfStrings;\r
+  EFI_STATUS                  Status;\r
+  LIST_ENTRY                  *Head;\r
+  SMBIOS_INSTANCE             *Private;\r
+  EFI_SMBIOS_ENTRY            *SmbiosEntry;\r
+  EFI_SMBIOS_HANDLE           MaxSmbiosHandle;\r
+  SMBIOS_HANDLE_ENTRY         *HandleEntry;\r
+  EFI_SMBIOS_RECORD_HEADER    *InternalRecord;\r
+  \r
+  if (SmbiosHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  //\r
+  // Check whether SmbiosHandle is already in use\r
+  //\r
+  Head = &Private->AllocatedHandleListHead;\r
+  if (*SmbiosHandle != 0 && CheckSmbiosHandleExistance(Head, *SmbiosHandle)) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  //\r
+  // when SmbiosHandle is zero, an available handle will be assigned\r
+  //\r
+  if (*SmbiosHandle == 0) {\r
+    Status = GetAvailableSmbiosHandle(This, SmbiosHandle);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+  } else {\r
+    //\r
+    // Check this handle validity\r
+    //\r
+    GetMaxSmbiosHandle(This, &MaxSmbiosHandle);\r
+    if (*SmbiosHandle > MaxSmbiosHandle) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Calculate record size and string number\r
+  //\r
+  Status = GetSmbiosStructureSize(Record, &StructureSize, &NumberOfStrings);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Enter into critical section\r
+  //  \r
+  Status = EfiAcquireLockOrFail (&Private->DataLock);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  RecordSize  = sizeof (EFI_SMBIOS_RECORD_HEADER) + StructureSize;\r
+  TotalSize   = sizeof (EFI_SMBIOS_ENTRY) + RecordSize;\r
+\r
+  //\r
+  // Allocate internal buffer\r
+  //\r
+  SmbiosEntry = AllocatePool (TotalSize);\r
+  if (SmbiosEntry == NULL) {\r
+    EfiReleaseLock (&Private->DataLock);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  HandleEntry = AllocatePool (sizeof(SMBIOS_HANDLE_ENTRY));\r
+  if (HandleEntry == NULL) {\r
+    EfiReleaseLock (&Private->DataLock);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Build Handle Entry and insert into linked list\r
+  //\r
+  ZeroMem(HandleEntry, sizeof(SMBIOS_HANDLE_ENTRY));\r
+  HandleEntry->Signature     = SMBIOS_HANDLE_ENTRY_SIGNATURE;\r
+  HandleEntry->SmbiosHandle  = *SmbiosHandle;\r
+  InsertTailList(&Private->AllocatedHandleListHead, &HandleEntry->Link);\r
+\r
+  ZeroMem (SmbiosEntry, TotalSize);\r
+  InternalRecord  = (EFI_SMBIOS_RECORD_HEADER *) (SmbiosEntry + 1);\r
+  Raw     = (VOID *) (InternalRecord + 1);\r
+\r
+  //\r
+  // Build internal record Header\r
+  //\r
+  InternalRecord->Version     = EFI_SMBIOS_RECORD_HEADER_VERSION;\r
+  InternalRecord->HeaderSize  = sizeof (EFI_SMBIOS_RECORD_HEADER);\r
+  InternalRecord->RecordSize  = RecordSize;\r
+  InternalRecord->ProducerHandle = ProducerHandle;\r
+  InternalRecord->NumberOfStrings = NumberOfStrings;\r
+  //\r
+  // Insert record into the internal linked list\r
+  //\r
+  SmbiosEntry->Signature    = EFI_SMBIOS_ENTRY_SIGNATURE;\r
+  SmbiosEntry->RecordHeader = InternalRecord;\r
+  SmbiosEntry->RecordSize   = TotalSize;\r
+  InsertTailList (&Private->DataListHead, &SmbiosEntry->Link);\r
+\r
+  CopyMem (Raw, Record, StructureSize);\r
+  ((EFI_SMBIOS_TABLE_HEADER*)Raw)->Handle = *SmbiosHandle;\r
+\r
+  //\r
+  // Leave critical section\r
+  //\r
+  EfiReleaseLock (&Private->DataLock);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update the string associated with an existing SMBIOS record.\r
+\r
+  @param  This                  The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  SmbiosHandle          SMBIOS Handle of structure that will have its string updated.\r
+  @param  StringNumber          The non-zero string number of the string to update\r
+  @param  String                Update the StringNumber string with String.\r
+\r
+  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.\r
+  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist.\r
+  @retval EFI_UNSUPPORTED       String was not added since it's longer than 64 significant characters.\r
+  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosUpdateString (\r
+  IN CONST EFI_SMBIOS_PROTOCOL      *This,\r
+  IN EFI_SMBIOS_HANDLE              *SmbiosHandle,\r
+  IN UINTN                          *StringNumber,\r
+  IN CHAR8                          *String\r
+  )\r
+{\r
+  UINTN                     InputStrLen;\r
+  UINTN                     TargetStrLen;\r
+  UINTN                     StrIndex;\r
+  UINTN                     TargetStrOffset;\r
+  UINTN                     NewEntrySize;\r
+  CHAR8                     *StrStart;\r
+  VOID                      *Raw;\r
+  LIST_ENTRY                *Link;\r
+  LIST_ENTRY                *Head;\r
+  EFI_STATUS                Status;\r
+  SMBIOS_INSTANCE           *Private;\r
+  EFI_SMBIOS_ENTRY          *SmbiosEntry;\r
+  EFI_SMBIOS_ENTRY          *ResizedSmbiosEntry;\r
+  EFI_SMBIOS_HANDLE         MaxSmbiosHandle;\r
+  EFI_SMBIOS_TABLE_HEADER   *Record;\r
+  EFI_SMBIOS_RECORD_HEADER  *InternalRecord;\r
+  \r
+  //\r
+  // Check args validity\r
+  //\r
+  GetMaxSmbiosHandle(This, &MaxSmbiosHandle);\r
+\r
+  if (*SmbiosHandle > MaxSmbiosHandle) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (String == NULL) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (*StringNumber == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  InputStrLen = AsciiStrLen(String);\r
+  if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  //\r
+  // Enter into critical section\r
+  //  \r
+  Status = EfiAcquireLockOrFail (&Private->DataLock);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Head = &Private->DataListHead;\r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
+    Record = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);\r
+\r
+    if ((UINTN)Record->Handle == *SmbiosHandle) {\r
+      //\r
+      // Find out the specified Smbios record\r
+      //\r
+      if (*StringNumber > SmbiosEntry->RecordHeader->NumberOfStrings) {\r
+        EfiReleaseLock (&Private->DataLock);\r
+        return EFI_NOT_FOUND;\r
+      }\r
+      //\r
+      // Point to unformed string section\r
+      //\r
+      StrStart = (CHAR8*)Record + Record->Length;\r
+     \r
+      for (StrIndex = 1, TargetStrOffset = 0; StrIndex < *StringNumber; StrStart++, TargetStrOffset++) {\r
+        //\r
+        // A string ends in 00h\r
+        //\r
+        if (*StrStart == 0) {\r
+          StrIndex++;\r
+        }\r
+        \r
+        //\r
+        // String section ends in double-null (0000h)\r
+        //\r
+        if (*StrStart == 0 && *(StrStart + 1) == 0) {\r
+          EfiReleaseLock (&Private->DataLock);\r
+          return EFI_NOT_FOUND;\r
+        } \r
+      }\r
+\r
+      //\r
+      // Now we get the string target\r
+      //\r
+      TargetStrLen = AsciiStrLen(StrStart);\r
+      if (InputStrLen == TargetStrLen) {\r
+        AsciiStrCpy(StrStart, String);\r
+        EfiReleaseLock (&Private->DataLock);\r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      //\r
+      // Original string buffer size is not exactly match input string length.\r
+      // Re-allocate buffer is needed.\r
+      //\r
+      NewEntrySize = SmbiosEntry->RecordSize + InputStrLen - TargetStrLen;\r
+      ResizedSmbiosEntry = AllocatePool (NewEntrySize);\r
+\r
+      if (ResizedSmbiosEntry == NULL) {\r
+        EfiReleaseLock (&Private->DataLock);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      ZeroMem (ResizedSmbiosEntry, NewEntrySize);\r
+      InternalRecord  = (EFI_SMBIOS_RECORD_HEADER *) (ResizedSmbiosEntry + 1);\r
+      Raw     = (VOID *) (InternalRecord + 1);\r
+\r
+      //\r
+      // Build internal record Header\r
+      //\r
+      InternalRecord->Version     = EFI_SMBIOS_RECORD_HEADER_VERSION;\r
+      InternalRecord->HeaderSize  = sizeof (EFI_SMBIOS_RECORD_HEADER);\r
+      InternalRecord->RecordSize  = SmbiosEntry->RecordHeader->RecordSize + InputStrLen - TargetStrLen;\r
+      InternalRecord->ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;\r
+      InternalRecord->NumberOfStrings = SmbiosEntry->RecordHeader->NumberOfStrings;\r
+\r
+      //\r
+      // Copy smbios structure and optional strings.\r
+      //\r
+      CopyMem (Raw, SmbiosEntry->RecordHeader + 1, sizeof(EFI_SMBIOS_TABLE_HEADER) + TargetStrOffset);\r
+      CopyMem ((VOID*)((UINTN)Raw + sizeof(EFI_SMBIOS_TABLE_HEADER) + TargetStrOffset), String, InputStrLen + 1);\r
+      AsciiStrCpy((CHAR8*)((UINTN)Raw + sizeof(EFI_SMBIOS_TABLE_HEADER) + TargetStrOffset + InputStrLen + 1), (CHAR8*)Record + Record->Length + TargetStrOffset + TargetStrLen + 1);\r
+\r
+      //\r
+      // Insert new record\r
+      //\r
+      ResizedSmbiosEntry->Signature    = EFI_SMBIOS_ENTRY_SIGNATURE;\r
+      ResizedSmbiosEntry->RecordHeader = InternalRecord;\r
+      ResizedSmbiosEntry->RecordSize   = NewEntrySize;\r
+      InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link);\r
+\r
+      //\r
+      // Remove old record\r
+      //\r
+      RemoveEntryList(Link);\r
+      FreePool(SmbiosEntry);\r
+      EfiReleaseLock (&Private->DataLock);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  EfiReleaseLock (&Private->DataLock);\r
+  return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+/**\r
+  Remove an SMBIOS record.\r
+\r
+  @param  This                  The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  SmbiosHandle          The handle of the SMBIOS record to remove.\r
+\r
+  @retval EFI_SUCCESS           SMBIOS record was removed.\r
+  @retval EFI_INVALID_PARAMETER SmbiosHandle does not specify a valid SMBIOS record.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosRemove (\r
+  IN CONST EFI_SMBIOS_PROTOCOL   *This,\r
+  IN EFI_SMBIOS_HANDLE           SmbiosHandle\r
+  )\r
+{\r
+  LIST_ENTRY                 *Link;\r
+  LIST_ENTRY                 *Head;\r
+  EFI_STATUS                 Status;\r
+  EFI_SMBIOS_HANDLE          MaxSmbiosHandle;\r
+  SMBIOS_INSTANCE            *Private;\r
+  EFI_SMBIOS_ENTRY           *SmbiosEntry;\r
+  SMBIOS_HANDLE_ENTRY        *HandleEntry;\r
+  EFI_SMBIOS_TABLE_HEADER    *Record;\r
+\r
+  //\r
+  // Check args validity\r
+  //\r
+  GetMaxSmbiosHandle(This, &MaxSmbiosHandle);\r
+\r
+  if (SmbiosHandle > MaxSmbiosHandle) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  //\r
+  // Enter into critical section\r
+  //  \r
+  Status = EfiAcquireLockOrFail (&Private->DataLock);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Head = &Private->DataListHead;\r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
+    Record = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);\r
+    if ((UINTN)Record->Handle == SmbiosHandle) {\r
+      //\r
+      // Remove specified smobios record from DataList\r
+      //\r
+      RemoveEntryList(Link);\r
+      FreePool(SmbiosEntry);\r
+      // \r
+      // Remove this handle from AllocatedHandleList\r
+      //\r
+      Head = &Private->AllocatedHandleListHead;\r
+      for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+        HandleEntry = SMBIOS_HANDLE_ENTRY_FROM_LINK(Link);\r
+        if ((UINTN)HandleEntry->SmbiosHandle == SmbiosHandle) {\r
+          RemoveEntryList(Link);\r
+          FreePool(HandleEntry);\r
+          break;\r
+        }\r
+      }\r
+      EfiReleaseLock (&Private->DataLock);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Leave critical section\r
+  //\r
+  EfiReleaseLock (&Private->DataLock);\r
+  return EFI_INVALID_PARAMETER;\r
+  \r
+}\r
+\r
+/**\r
+  Allow the caller to discover all or some of the SMBIOS records.\r
+\r
+  @param  This                  The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  SmbiosHandle          On entry, points to the previous handle of the SMBIOS record. On exit, points to the\r
+                                next SMBIOS record handle. If it is zero on entry, then the first SMBIOS record\r
+                                handle will be returned. If it returns zero on exit, then there are no more SMBIOS records.\r
+  @param  Type                  On entry it means return the next SMBIOS record of type Type. If a NULL is passed in \r
+                                this functionally it ignored. Type is not modified by the GetNext() function.\r
+  @param  Record                On exit, points to the SMBIOS Record consisting of the formatted area followed by\r
+                                the unformatted area. The unformatted area optionally contains text strings.\r
+  @param  ProducerHandle        On exit, points to the ProducerHandle registered by Add(). If no ProducerHandle was passed into Add() NULL is returned. \r
+                                If a NULL pointer is passed in no data will be returned \r
+                                \r
+  @retval EFI_SUCCESS           SMBIOS record information was successfully returned in Record.\r
+                                SmbiosHandle is the handle of the current SMBIOS record\r
+  @retval EFI_NOT_FOUND         The SMBIOS record with SmbiosHandle was the last available record.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosGetNext (\r
+  IN CONST EFI_SMBIOS_PROTOCOL      *This,\r
+  IN OUT EFI_SMBIOS_HANDLE          *SmbiosHandle,\r
+  IN EFI_SMBIOS_TYPE                *Type,          OPTIONAL\r
+  OUT EFI_SMBIOS_TABLE_HEADER       **Record,\r
+  OUT EFI_HANDLE                    *ProducerHandle OPTIONAL\r
+  )\r
+{\r
+  BOOLEAN                  StartPointFound;\r
+  LIST_ENTRY               *Link;\r
+  LIST_ENTRY               *Head;\r
+  SMBIOS_INSTANCE          *Private;\r
+  EFI_SMBIOS_ENTRY         *SmbiosEntry;\r
+  EFI_SMBIOS_TABLE_HEADER  *SmbiosTableHeader;\r
+\r
+  if (SmbiosHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  StartPointFound = FALSE;\r
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  Head = &Private->DataListHead;\r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
+    SmbiosTableHeader = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1); \r
+\r
+    //\r
+    // If SmbiosHandle is zero, the first matched SMBIOS record handle will be returned\r
+    //\r
+    if (*SmbiosHandle == 0) {\r
+      if ((Type != NULL) && (*Type != SmbiosTableHeader->Type)) {\r
+        continue;  \r
+      }\r
+\r
+      *SmbiosHandle = SmbiosTableHeader->Handle;\r
+      *Record =SmbiosTableHeader;\r
+      if (ProducerHandle != NULL) {\r
+        *ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;\r
+      }\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    //\r
+    // Start this round search from the next Smbios handle\r
+    //\r
+    if (!StartPointFound && (*SmbiosHandle == SmbiosTableHeader->Handle)) {\r
+      StartPointFound = TRUE;\r
+      continue;\r
+    }\r
+\r
+    if (StartPointFound) {\r
+      if ((Type != NULL) && (*Type != SmbiosTableHeader->Type)) {\r
+        continue; \r
+      }\r
+      \r
+      *SmbiosHandle = SmbiosTableHeader->Handle;\r
+      *Record = SmbiosTableHeader; \r
+      if (ProducerHandle != NULL) {\r
+        *ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;\r
+      }\r
+\r
+      return EFI_SUCCESS;   \r
+    }\r
+  }\r
+\r
+  *SmbiosHandle = 0;\r
+  return EFI_NOT_FOUND;\r
+  \r
+}\r
+\r
+\r
+/**\r
+  Assembles Smbios table from the SMBIOS protocol. Produce Table\r
+  Entry Point and return the pointer to it.\r
+  \r
+  @param  TableEntryPointStructure   On exit, points to the SMBIOS entrypoint structure.\r
+                                \r
+  @retval EFI_SUCCESS                Structure created sucessfully.\r
+  @retval EFI_NOT_READY              Some of The SMBIOS records was not available yet.\r
+  @retval EFI_OUT_OF_RESOURCES       No enough memory.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosCreateTable (\r
+  OUT VOID    **TableEntryPointStructure\r
+  )\r
+{\r
+  UINT8                           CheckSum;\r
+  UINT8                           *BufferPointer;\r
+  UINTN                           Index;\r
+  UINTN                           RecordSize;\r
+  UINTN                           NumOfStr;\r
+  EFI_STATUS                      Status;\r
+  EFI_SMBIOS_HANDLE               SmbiosHandle;\r
+  EFI_SMBIOS_PROTOCOL             *SmbiosProtocol;\r
+  EFI_PHYSICAL_ADDRESS            PhysicalAddress;\r
+  EFI_SMBIOS_TABLE_HEADER         *SmbiosRecord;\r
+  EFI_SMBIOS_TABLE_END_STRUCTURE  EndStructure;\r
+  \r
+  Status            = EFI_SUCCESS;\r
+  BufferPointer     = NULL;\r
+  CheckSum          = 0;\r
+\r
+  //\r
+  // Initialize the EntryPointStructure with initial values.\r
+  //\r
+  if (EntryPointStructure == NULL) {\r
+    //\r
+    // Allocate memory (below 4GB)\r
+    //\r
+    PhysicalAddress = 0xffffffff;\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiReservedMemoryType,\r
+                    EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
+                    &PhysicalAddress\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) (UINTN) PhysicalAddress;\r
+    \r
+    CopyMem (\r
+      EntryPointStructure,\r
+      &EntryPointStructureData,\r
+      sizeof (SMBIOS_TABLE_ENTRY_POINT)\r
+      );\r
+  }\r
+\r
+  //\r
+  // Free the original image\r
+  //\r
+  if (EntryPointStructure->TableAddress) {\r
+    FreePages (\r
+          (VOID*)(UINTN)EntryPointStructure->TableAddress,\r
+          EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength)\r
+          );\r
+    EntryPointStructure->TableAddress = 0;\r
+  }\r
+  \r
+  //\r
+  // Locate smbios protocol to traverse smbios records.\r
+  //\r
+  gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &SmbiosProtocol);\r
+  \r
+  ASSERT (SmbiosProtocol != NULL);\r
+\r
+  //\r
+  // Make some statistics about all the structures\r
+  //\r
+  EntryPointStructure->NumberOfSmbiosStructures = 0;\r
+  EntryPointStructure->TableLength              = 0;\r
+  EntryPointStructure->MaxStructureSize         = 0;\r
+  SmbiosHandle = 0;\r
+\r
+  //\r
+  // Calculate EPS Table Length\r
+  //\r
+  do {\r
+    Status = SmbiosProtocol->GetNext (\r
+                               SmbiosProtocol,\r
+                               &SmbiosHandle,\r
+                               NULL,\r
+                               &SmbiosRecord,\r
+                               NULL\r
+                               );\r
+                               \r
+    if (Status == EFI_SUCCESS) {\r
+      GetSmbiosStructureSize(SmbiosRecord, &RecordSize, &NumOfStr);\r
+      //\r
+      // Record NumberOfSmbiosStructures, TableLength and MaxStructureSize\r
+      //\r
+      EntryPointStructure->NumberOfSmbiosStructures++;\r
+      EntryPointStructure->TableLength = (UINT16) (EntryPointStructure->TableLength + RecordSize);\r
+      if (RecordSize > EntryPointStructure->MaxStructureSize) {\r
+        EntryPointStructure->MaxStructureSize = (UINT16) RecordSize;\r
+      }\r
+    }\r
+  } while (!EFI_ERROR(Status));\r
+  \r
+  //\r
+  // Create End-Of-Table structure\r
+  //\r
+  GetMaxSmbiosHandle(SmbiosProtocol, &SmbiosHandle);\r
+  EndStructure.Header.Type = EFI_SMBIOS_TYPE_END_OF_TABLE;\r
+  EndStructure.Header.Length = sizeof(EFI_SMBIOS_TABLE_HEADER);\r
+  EndStructure.Header.Handle = SmbiosHandle;\r
+  EndStructure.Tailing[0] = 0;\r
+  EndStructure.Tailing[1] = 0;\r
+  EntryPointStructure->NumberOfSmbiosStructures++;\r
+  EntryPointStructure->TableLength = (UINT16) (EntryPointStructure->TableLength + sizeof (EndStructure));\r
+  if (sizeof (EndStructure) > EntryPointStructure->MaxStructureSize) {\r
+    EntryPointStructure->MaxStructureSize = (UINT16) sizeof (EndStructure);\r
+  }\r
+  \r
+  //\r
+  // Allocate memory (below 4GB)\r
+  //\r
+  PhysicalAddress = 0xffffffff;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiReservedMemoryType,\r
+                  EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength),\r
+                  &PhysicalAddress\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePages ((VOID*)(UINTN)EntryPointStructure, EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength));\r
+    EntryPointStructure = NULL;\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+  \r
+  //\r
+  // Assemble the tables\r
+  //\r
+  BufferPointer = (UINT8 *) (UINTN) PhysicalAddress;\r
+  SmbiosHandle = 0;\r
+  do {\r
+    Status = SmbiosProtocol->GetNext (\r
+                               SmbiosProtocol,\r
+                               &SmbiosHandle,\r
+                               NULL,\r
+                               &SmbiosRecord,\r
+                               NULL\r
+                               );\r
+    if (Status == EFI_SUCCESS) {\r
+      GetSmbiosStructureSize(SmbiosRecord, &RecordSize, &NumOfStr);\r
+      CopyMem (BufferPointer, SmbiosRecord, RecordSize);\r
+      BufferPointer = BufferPointer + RecordSize;\r
+    }\r
+  } while (!EFI_ERROR(Status));\r
+  \r
+  //\r
+  // Assemble End-Of-Table structure\r
+  //\r
+  CopyMem (BufferPointer, &EndStructure, sizeof (EndStructure));\r
+\r
+  //\r
+  // Fixup checksums in the Entry Point Structure\r
+  //\r
+  CheckSum  = 0;\r
+  EntryPointStructure->IntermediateChecksum = 0;\r
+  for (Index = 0x10; Index < EntryPointStructure->EntryPointLength; Index++) {\r
+    CheckSum = (UINT8) (CheckSum + ((UINT8 *) (EntryPointStructure))[Index]);\r
+  }\r
+\r
+  EntryPointStructure->IntermediateChecksum         = (UINT8) (0 - CheckSum);\r
+\r
+  CheckSum = 0;\r
+  EntryPointStructure->EntryPointStructureChecksum = 0;\r
+  for (Index = 0x0; Index < EntryPointStructure->EntryPointLength; Index++) {\r
+    CheckSum = (UINT8) (CheckSum + ((UINT8 *) (EntryPointStructure))[Index]);\r
+  }\r
+\r
+  EntryPointStructure->EntryPointStructureChecksum = (UINT8) (0 - CheckSum);\r
+\r
+  //\r
+  // Returns the pointer\r
+  //\r
+  *TableEntryPointStructure = EntryPointStructure;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Installs the Smbios Table to the System Table. This function gets called\r
+  when the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled\r
+  \r
+  @param  Event                The event to signal\r
+  @param  Context              Event contex\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SmbiosTableConstruction (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  UINT8       *Eps;\r
+  EFI_STATUS  Status;\r
+\r
+  Status = SmbiosCreateTable ((VOID **) &Eps);\r
+  if (!EFI_ERROR (Status)) {\r
+    gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, Eps);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+\r
+  Driver to produce Smbios protocol and register event for constructing SMBIOS table. \r
+\r
+  @param ImageHandle     Module's image handle\r
+  @param SystemTable     Pointer of EFI_SYSTEM_TABLE\r
+\r
+  @retval EFI_SUCCESS    Smbios protocol installed\r
+  @retval Other          No protocol installed, unload driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosDriverEntryPoint (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_EVENT             ReadyToBootEvent;\r
+\r
+  mPrivateData.Signature                = SMBIOS_INSTANCE_SIGNATURE;\r
+  mPrivateData.Smbios.Add               = SmbiosAdd;\r
+  mPrivateData.Smbios.UpdateString      = SmbiosUpdateString;\r
+  mPrivateData.Smbios.Remove            = SmbiosRemove;\r
+  mPrivateData.Smbios.GetNext           = SmbiosGetNext;\r
+  mPrivateData.Smbios.MajorVersion      = SMBIOS_MAJOR_VERSION;\r
+  mPrivateData.Smbios.MinorVersion      = SMBIOS_MINOR_VERSION;\r
+\r
+  InitializeListHead (&mPrivateData.DataListHead);\r
+  InitializeListHead (&mPrivateData.AllocatedHandleListHead);\r
+  EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);\r
+  \r
+  //\r
+  // Make a new handle and install the protocol\r
+  //\r
+  mPrivateData.Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &mPrivateData.Handle,\r
+                  &gEfiSmbiosProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &mPrivateData.Smbios\r
+                  );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Register the event to install SMBIOS Table into EFI System Table\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  SmbiosTableConstruction,\r
+                  NULL,\r
+                  &gEfiEventReadyToBootGuid,\r
+                  &ReadyToBootEvent\r
+                  );\r
+  \r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h
new file mode 100644 (file)
index 0000000..f75429c
--- /dev/null
@@ -0,0 +1,114 @@
+/** @file\r
+  This code supports the implementation of the Smbios protocol\r
+  \r
+Copyright (c) 2009, Intel Corporation                                                         \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
+**/\r
+\r
+#ifndef _SMBIOS_DXE_H_\r
+#define _SMBIOS_DXE_H_\r
+\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Smbios.h>\r
+#include <IndustryStandard/SmBios.h>\r
+#include <Guid/EventGroup.h>\r
+#include <Guid/SmBios.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#define SMBIOS_MAJOR_VERSION 2\r
+#define SMBIOS_MINOR_VERSION 4\r
+\r
+\r
+#define SMBIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'B', 'i', 's')\r
+typedef struct {\r
+  UINT32                Signature;\r
+  EFI_HANDLE            Handle;\r
+  //\r
+  // Produced protocol\r
+  //\r
+  EFI_SMBIOS_PROTOCOL   Smbios;\r
+  //\r
+  // Updates to record list must be locked.\r
+  //\r
+  EFI_LOCK              DataLock;\r
+  //\r
+  // List of EFI_SMBIOS_ENTRY structures.\r
+  //\r
+  LIST_ENTRY            DataListHead;\r
+  //\r
+  // List of allocated SMBIOS handle.\r
+  //\r
+  LIST_ENTRY            AllocatedHandleListHead;\r
+} SMBIOS_INSTANCE;\r
+\r
+#define SMBIOS_INSTANCE_FROM_THIS(this)  CR (this, SMBIOS_INSTANCE, Smbios, SMBIOS_INSTANCE_SIGNATURE)\r
+\r
+//\r
+// SMBIOS record Header\r
+//\r
+// An SMBIOS internal Record is an EFI_SMBIOS_RECORD_HEADER followed by (RecordSize - HeaderSize) bytes of\r
+//  data. The format of the data is defined by the SMBIOS spec.\r
+//\r
+//\r
+#define EFI_SMBIOS_RECORD_HEADER_VERSION  0x0100\r
+typedef struct {\r
+  UINT16      Version;\r
+  UINT16      HeaderSize;\r
+  UINTN       RecordSize;\r
+  EFI_HANDLE  ProducerHandle;\r
+  UINTN       NumberOfStrings;\r
+} EFI_SMBIOS_RECORD_HEADER;\r
+\r
+\r
+//\r
+// Private data structure to contain the SMBIOS record. One record per\r
+//  structure. SmbiosRecord is a copy of the data passed in and follows RecordHeader .\r
+//\r
+#define EFI_SMBIOS_ENTRY_SIGNATURE  SIGNATURE_32 ('S', 'r', 'e', 'c')\r
+typedef struct {\r
+  UINT32                    Signature;\r
+  LIST_ENTRY                Link;\r
+  EFI_SMBIOS_RECORD_HEADER  *RecordHeader;\r
+  UINTN                     RecordSize;\r
+} EFI_SMBIOS_ENTRY;\r
+\r
+#define SMBIOS_ENTRY_FROM_LINK(link)  CR (link, EFI_SMBIOS_ENTRY, Link, EFI_SMBIOS_ENTRY_SIGNATURE)\r
+\r
+//\r
+// Private data to contain the Smbios handle that already allocated.\r
+//\r
+#define SMBIOS_HANDLE_ENTRY_SIGNATURE  SIGNATURE_32 ('S', 'h', 'r', 'd')\r
+\r
+typedef struct {\r
+  UINT32               Signature;\r
+  LIST_ENTRY           Link;\r
+  //\r
+  // Filter driver will register what record guid filter should be used.\r
+  //\r
+  EFI_SMBIOS_HANDLE    SmbiosHandle;\r
+\r
+} SMBIOS_HANDLE_ENTRY;\r
+\r
+#define SMBIOS_HANDLE_ENTRY_FROM_LINK(link)  CR (link, SMBIOS_HANDLE_ENTRY, Link, SMBIOS_HANDLE_ENTRY_SIGNATURE)\r
+\r
+typedef struct {\r
+  EFI_SMBIOS_TABLE_HEADER  Header;\r
+  UINT8                    Tailing[2];\r
+} EFI_SMBIOS_TABLE_END_STRUCTURE;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
new file mode 100644 (file)
index 0000000..17d9d83
--- /dev/null
@@ -0,0 +1,58 @@
+#/** @file\r
+# Component description file for Smbios module.\r
+#\r
+# This driver initializes and installs the SMBIOS protocol.\r
+# Copyright (c) 2009, Intel Corporation\r
+#\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
+#  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
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmbiosDxe\r
+  FILE_GUID                      = F9D88642-0737-49bc-81B5-6889CD57D9EA\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = SmbiosDriverEntryPoint\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  SmbiosDxe.h\r
+  SmbiosDxe.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  BaseLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+\r
+[Protocols]\r
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_PRODUCED\r
+  \r
+[Guids]\r
+  gEfiEventReadyToBootGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiSmbiosTableGuid                         # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Depex]\r
+  TRUE\r