]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Create smbios table when user adds/removes/Updatestring for a SMBIOS entry. It is...
authorli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Aug 2011 07:30:02 +0000 (07:30 +0000)
committerli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Aug 2011 07:30:02 +0000 (07:30 +0000)
Signed-off-by: li-elvin
Reviewed-by: lzeng14
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12067 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h

index 8b2efa14a1072ec0baaba961bef9c242547db68e..56ece92c9a37129f5c13345eb85d680480f6f6f5 100644 (file)
@@ -105,15 +105,15 @@ SMBIOS_TABLE_ENTRY_POINT EntryPointStructureData = {
 \r
 /**\r
 \r
-  Get the full size of smbios structure including optional strings that follow the formatted structure.\r
+  Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
 \r
   @param This                   The EFI_SMBIOS_PROTOCOL instance.\r
-  @param Head                   Pointer to the beginning of smbios structure.\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
+  @retval EFI_INVALID_PARAMETER Input SMBIOS structure mal-formed or Size is NULL.\r
   \r
 **/\r
 EFI_STATUS\r
@@ -187,7 +187,7 @@ GetSmbiosStructureSize (
 \r
   Determin whether an SmbiosHandle has already in use.\r
 \r
-  @param Head        Pointer to the beginning of smbios structure.\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
@@ -408,6 +408,14 @@ SmbiosAdd (
   CopyMem (Raw, Record, StructureSize);\r
   ((EFI_SMBIOS_TABLE_HEADER*)Raw)->Handle = *SmbiosHandle;\r
 \r
+  //\r
+  // Some UEFI drivers (such as network) need some information in SMBIOS table.\r
+  // Here we create SMBIOS table and publish it in\r
+  // configuration table, so other UEFI drivers can get SMBIOS table from\r
+  // configuration table without depending on PI SMBIOS protocol.\r
+  //\r
+  SmbiosTableConstruction ();\r
+  \r
   //\r
   // Leave critical section\r
   //\r
@@ -499,7 +507,7 @@ SmbiosUpdateString (
 \r
     if (Record->Handle == *SmbiosHandle) {\r
       //\r
-      // Find out the specified Smbios record\r
+      // Find out the specified SMBIOS record\r
       //\r
       if (*StringNumber > SmbiosEntry->RecordHeader->NumberOfStrings) {\r
         EfiReleaseLock (&Private->DataLock);\r
@@ -538,6 +546,13 @@ SmbiosUpdateString (
       TargetStrLen = AsciiStrLen(StrStart);\r
       if (InputStrLen == TargetStrLen) {\r
         AsciiStrCpy(StrStart, String);\r
+        //\r
+        // Some UEFI drivers (such as network) need some information in SMBIOS table.\r
+        // Here we create SMBIOS table and publish it in\r
+        // configuration table, so other UEFI drivers can get SMBIOS table from\r
+        // configuration table without depending on PI SMBIOS protocol.\r
+        //\r
+        SmbiosTableConstruction ();\r
         EfiReleaseLock (&Private->DataLock);\r
         return EFI_SUCCESS;\r
       }\r
@@ -567,7 +582,7 @@ SmbiosUpdateString (
       InternalRecord->NumberOfStrings = SmbiosEntry->RecordHeader->NumberOfStrings;\r
 \r
       //\r
-      // Copy smbios structure and optional strings.\r
+      // Copy SMBIOS structure and optional strings.\r
       //\r
       CopyMem (Raw, SmbiosEntry->RecordHeader + 1, Record->Length + TargetStrOffset);\r
       CopyMem ((VOID*)((UINTN)Raw + Record->Length + TargetStrOffset), String, InputStrLen + 1);\r
@@ -588,6 +603,13 @@ SmbiosUpdateString (
       //\r
       RemoveEntryList(Link);\r
       FreePool(SmbiosEntry);\r
+      //\r
+      // Some UEFI drivers (such as network) need some information in SMBIOS table.\r
+      // Here we create SMBIOS table and publish it in\r
+      // configuration table, so other UEFI drivers can get SMBIOS table from\r
+      // configuration table without depending on PI SMBIOS protocol.\r
+      //\r
+      SmbiosTableConstruction ();\r
       EfiReleaseLock (&Private->DataLock);\r
       return EFI_SUCCESS;\r
     }\r
@@ -663,6 +685,13 @@ SmbiosRemove (
           break;\r
         }\r
       }\r
+      //\r
+      // Some UEFI drivers (such as network) need some information in SMBIOS table.\r
+      // Here we create SMBIOS table and publish it in\r
+      // configuration table, so other UEFI drivers can get SMBIOS table from\r
+      // configuration table without depending on PI SMBIOS protocol.\r
+      //\r
+      SmbiosTableConstruction ();\r
       EfiReleaseLock (&Private->DataLock);\r
       return EFI_SUCCESS;\r
     }\r
@@ -691,7 +720,6 @@ SmbiosRemove (
                                 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
@@ -740,7 +768,7 @@ SmbiosGetNext (
     }\r
 \r
     //\r
-    // Start this round search from the next Smbios handle\r
+    // Start this round search from the next SMBIOS handle\r
     //\r
     if (!StartPointFound && (*SmbiosHandle == SmbiosTableHeader->Handle)) {\r
       StartPointFound = TRUE;\r
@@ -767,9 +795,65 @@ SmbiosGetNext (
   \r
 }\r
 \r
+/**\r
+  Allow the caller to discover all of the SMBIOS records.\r
+\r
+  @param  This                  The EFI_SMBIOS_PROTOCOL instance.\r
+  @param  CurrentSmbiosEntry    On exit, points to the SMBIOS entry on the list which includes the returned SMBIOS record information. \r
+                                If *CurrentSmbiosEntry is NULL on entry, then the first SMBIOS entry on the list will be returned. \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
+                                \r
+  @retval EFI_SUCCESS           SMBIOS record information was successfully returned in Record.\r
+                                *CurrentSmbiosEntry points to the SMBIOS entry which includes the returned SMBIOS record information.\r
+  @retval EFI_NOT_FOUND         There is no more SMBIOS entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetNextSmbiosRecord (\r
+  IN CONST EFI_SMBIOS_PROTOCOL         *This,\r
+  IN OUT EFI_SMBIOS_ENTRY              **CurrentSmbiosEntry,\r
+  OUT EFI_SMBIOS_TABLE_HEADER          **Record\r
+  )\r
+{\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
+  Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
+  if (*CurrentSmbiosEntry == NULL) {\r
+    //\r
+    // Get the beginning of SMBIOS entry.\r
+    //\r
+    Head = &Private->DataListHead;\r
+  } else {\r
+    //\r
+    // Get previous SMBIOS entry and make it as start point.\r
+    //\r
+    Head = &(*CurrentSmbiosEntry)->Link;\r
+  }\r
+  \r
+  Link  = Head->ForwardLink;\r
+  \r
+  if (Link == &Private->DataListHead) {\r
+    //\r
+    // If no more SMBIOS entry in the list, return not found.\r
+    //\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
+  SmbiosTableHeader = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);\r
+  *Record = SmbiosTableHeader; \r
+  *CurrentSmbiosEntry = SmbiosEntry;\r
+  return EFI_SUCCESS;   \r
+}\r
 \r
 /**\r
-  Assembles Smbios table from the SMBIOS protocol. Produce Table\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
@@ -794,54 +878,18 @@ SmbiosCreateTable (
   EFI_PHYSICAL_ADDRESS            PhysicalAddress;\r
   EFI_SMBIOS_TABLE_HEADER         *SmbiosRecord;\r
   EFI_SMBIOS_TABLE_END_STRUCTURE  EndStructure;\r
+  EFI_SMBIOS_ENTRY                *CurrentSmbiosEntry;\r
+  UINTN                           PreAllocatedPages;\r
   \r
   Status            = EFI_SUCCESS;\r
   BufferPointer     = NULL;\r
 \r
   //\r
-  // Initialize the EntryPointStructure with initial values.\r
+  // Get Smbios protocol to traverse SMBIOS records.\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
+  SmbiosProtocol = &mPrivateData.Smbios;\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 != 0) {\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
-  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &SmbiosProtocol);\r
-  ASSERT_EFI_ERROR (Status);\r
-  ASSERT (SmbiosProtocol != NULL);\r
+  PreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
 \r
   //\r
   // Make some statistics about all the structures\r
@@ -849,19 +897,13 @@ SmbiosCreateTable (
   EntryPointStructure->NumberOfSmbiosStructures = 0;\r
   EntryPointStructure->TableLength              = 0;\r
   EntryPointStructure->MaxStructureSize         = 0;\r
-  SmbiosHandle = 0;\r
 \r
   //\r
   // Calculate EPS Table Length\r
   //\r
+  CurrentSmbiosEntry = NULL;\r
   do {\r
-    Status = SmbiosProtocol->GetNext (\r
-                               SmbiosProtocol,\r
-                               &SmbiosHandle,\r
-                               NULL,\r
-                               &SmbiosRecord,\r
-                               NULL\r
-                               );\r
+    Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
                                \r
     if (Status == EFI_SUCCESS) {\r
       GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
@@ -890,38 +932,44 @@ SmbiosCreateTable (
   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*) EntryPointStructure, EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)));\r
-    EntryPointStructure = NULL;\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
 \r
-  EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+  if (EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > PreAllocatedPages) {\r
+    //\r
+    // If new SMBIOS talbe size exceeds the original pre-allocated page, \r
+    // it is time to re-allocate memory (below 4GB).\r
+    // \r
+    if (EntryPointStructure->TableAddress != 0) {\r
+      //\r
+      // Free the original pre-allocated page\r
+      //      \r
+      FreePages (\r
+            (VOID*)(UINTN)EntryPointStructure->TableAddress,\r
+            PreAllocatedPages\r
+            );\r
+      EntryPointStructure->TableAddress = 0;\r
+    }\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
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+  }\r
   \r
   //\r
   // Assemble the tables\r
   //\r
-  BufferPointer = (UINT8 *) (UINTN) PhysicalAddress;\r
-  SmbiosHandle = 0;\r
+  BufferPointer = (UINT8 *) (UINTN) EntryPointStructure->TableAddress;\r
+  CurrentSmbiosEntry = NULL;\r
   do {\r
-    Status = SmbiosProtocol->GetNext (\r
-                               SmbiosProtocol,\r
-                               &SmbiosHandle,\r
-                               NULL,\r
-                               &SmbiosRecord,\r
-                               NULL\r
-                               );\r
+    Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
+\r
     if (Status == EFI_SUCCESS) {\r
       GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
       CopyMem (BufferPointer, SmbiosRecord, RecordSize);\r
@@ -950,21 +998,13 @@ SmbiosCreateTable (
   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
+  Create SMBIOS Table and install it to the System Table.\r
 **/\r
 VOID\r
 EFIAPI\r
 SmbiosTableConstruction (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
+  VOID\r
   )\r
 {\r
   UINT8       *Eps;\r
@@ -976,10 +1016,9 @@ SmbiosTableConstruction (
   }\r
 }\r
 \r
-\r
 /**\r
 \r
-  Driver to produce Smbios protocol and register event for constructing SMBIOS table. \r
+  Driver to produce Smbios protocol and pre-allocate 1 page for the final SMBIOS table. \r
 \r
   @param ImageHandle     Module's image handle\r
   @param SystemTable     Pointer of EFI_SYSTEM_TABLE\r
@@ -996,7 +1035,7 @@ SmbiosDriverEntryPoint (
   )\r
 {\r
   EFI_STATUS            Status;\r
-  EFI_EVENT             ReadyToBootEvent;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
 \r
   mPrivateData.Signature                = SMBIOS_INSTANCE_SIGNATURE;\r
   mPrivateData.Smbios.Add               = SmbiosAdd;\r
@@ -1009,7 +1048,52 @@ SmbiosDriverEntryPoint (
   InitializeListHead (&mPrivateData.DataListHead);\r
   InitializeListHead (&mPrivateData.AllocatedHandleListHead);\r
   EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);\r
+\r
+  //\r
+  // Initialize the EntryPointStructure with initial values.\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
+  // Pre-allocate 1 page for SMBIOS table below 4GB.\r
+  // SMBIOS table will be updated when new SMBIOS type is added or \r
+  // existing SMBIOS type is updated. If the total size of SMBIOS table exceeds 1 page,\r
+  // we will re-allocate new memory when creating whole SMBIOS table.\r
+  //\r
+  PhysicalAddress = 0xffffffff;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiReservedMemoryType,\r
+                  1,\r
+                  &PhysicalAddress\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePages ((VOID*) EntryPointStructure, EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)));\r
+    EntryPointStructure = NULL;\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+  EntryPointStructure->TableLength  = EFI_PAGES_TO_SIZE (1);\r
+\r
   //\r
   // Make a new handle and install the protocol\r
   //\r
@@ -1021,20 +1105,5 @@ SmbiosDriverEntryPoint (
                   &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
index 6000bda3cf01284c3d5157093d4380b9f4da005b..3c78b993bd64d9eaada8fd3c15fbb9b6f570979a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This code supports the implementation of the Smbios protocol\r
   \r
-Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -108,4 +108,13 @@ typedef struct {
   UINT8                    Tailing[2];\r
 } EFI_SMBIOS_TABLE_END_STRUCTURE;\r
 \r
+/**\r
+  Create Smbios Table and installs the Smbios Table to the System Table.\r
+**/\r
+VOID\r
+EFIAPI\r
+SmbiosTableConstruction (\r
+  VOID\r
+  );\r
+\r
 #endif\r