]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c
MdeModulePkg/IntelFrameworkModulePkg: Update PeiCore, SmbiosDxe and IsaSerialDxe...
[mirror_edk2.git] / MdeModulePkg / Universal / SmbiosDxe / SmbiosDxe.c
index 2d0be7cd51485f6696573725f6dc4cfebbd382e0..c0128f088f9e12a5fd69e86f35f7a857248a81f6 100644 (file)
@@ -2,7 +2,7 @@
   This code produces the Smbios protocol. It also responsible for constructing \r
   SMBIOS table into system table.\r
   \r
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2014, 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
@@ -22,6 +22,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 SMBIOS_INSTANCE mPrivateData;\r
 \r
+UINTN mPreAllocatedPages = 0;\r
+\r
 //\r
 // Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.\r
 //\r
@@ -47,11 +49,11 @@ SMBIOS_TABLE_ENTRY_POINT EntryPointStructureData = {
   //\r
   // MajorVersion\r
   //\r
-  (UINT8) (FixedPcdGet16 (PcdSmbiosVersion) >> 8),\r
+  0,\r
   //\r
   // MinorVersion\r
   //\r
-  (UINT8) (FixedPcdGet16 (PcdSmbiosVersion) & 0x00ff),\r
+  0,\r
   //\r
   // MaxStructureSize, TO BE FILLED\r
   //\r
@@ -85,11 +87,11 @@ SMBIOS_TABLE_ENTRY_POINT EntryPointStructureData = {
   //\r
   0,\r
   //\r
-  // StructureTableLength, TO BE FILLED\r
+  // TableLength, TO BE FILLED\r
   //\r
   0,\r
   //\r
-  // StructureTableAddress, TO BE FILLED\r
+  // TableAddress, TO BE FILLED\r
   //\r
   0,\r
   //\r
@@ -99,7 +101,7 @@ SMBIOS_TABLE_ENTRY_POINT EntryPointStructureData = {
   //\r
   // SmbiosBcdRevision\r
   //\r
-  0  \r
+  0\r
 };\r
 \r
 \r
@@ -128,6 +130,7 @@ GetSmbiosStructureSize (
 {\r
   UINTN  FullSize;\r
   UINTN  StrLen;\r
+  UINTN  MaxLen;\r
   INT8*  CharInStr;\r
   \r
   if (Size == NULL || NumberOfStrings == NULL) {\r
@@ -149,26 +152,27 @@ GetSmbiosStructureSize (
     }\r
 \r
     if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)){\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
+      MaxLen = SMBIOS_STRING_MAX_LENGTH;\r
     } else {\r
       //\r
-      // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string\r
+      // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
+      // However, the length of the entire structure table (including all strings) must be reported\r
+      // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+      // which is a WORD field limited to 65,535 bytes.\r
       //\r
-      for (StrLen = 0 ;; StrLen++) {\r
-        if (*(CharInStr+StrLen) == 0) {\r
-          break;\r
-        }\r
+      MaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
+    }\r
+\r
+    for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {\r
+      if (*(CharInStr+StrLen) == 0) {\r
+        break;\r
       }\r
     }\r
 \r
+    if (StrLen == MaxLen) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     //\r
     // forward the pointer\r
     //\r
@@ -355,6 +359,15 @@ SmbiosAdd (
     return Status;\r
   }\r
 \r
+  if (EntryPointStructure->TableLength + StructureSize > SMBIOS_TABLE_MAX_LENGTH) {\r
+    //\r
+    // The length of the entire structure table (including all strings) must be reported\r
+    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+    // which is a WORD field limited to 65,535 bytes.\r
+    //\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Enter into critical section\r
   //  \r
@@ -483,13 +496,20 @@ SmbiosUpdateString (
 \r
   InputStrLen = AsciiStrLen(String);\r
 \r
-  //\r
-  // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string\r
-  //\r
   if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {\r
     if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
       return EFI_UNSUPPORTED;\r
     }\r
+  } else {\r
+    //\r
+    // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
+    // However, the length of the entire structure table (including all strings) must be reported \r
+    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+    // which is a WORD field limited to 65,535 bytes.\r
+    //\r
+    if (InputStrLen > SMBIOS_TABLE_MAX_LENGTH) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
   }\r
 \r
   Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
@@ -558,6 +578,15 @@ SmbiosUpdateString (
         return EFI_SUCCESS;\r
       }\r
 \r
+      if (EntryPointStructure->TableLength + InputStrLen - TargetStrLen > SMBIOS_TABLE_MAX_LENGTH) {\r
+        //\r
+        // The length of the entire structure table (including all strings) must be reported\r
+        // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+        // which is a WORD field limited to 65,535 bytes.\r
+        //\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
       //\r
       // Original string buffer size is not exactly match input string length.\r
       // Re-allocate buffer is needed.\r
@@ -880,7 +909,6 @@ SmbiosCreateTable (
   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
@@ -890,12 +918,6 @@ SmbiosCreateTable (
   //\r
   SmbiosProtocol = &mPrivateData.Smbios;\r
 \r
-  if (EntryPointStructure->TableAddress == 0) {\r
-    PreAllocatedPages = 0;\r
-  } else {\r
-    PreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
-  }\r
-\r
   //\r
   // Make some statistics about all the structures\r
   //\r
@@ -938,7 +960,7 @@ SmbiosCreateTable (
     EntryPointStructure->MaxStructureSize = (UINT16) sizeof (EndStructure);\r
   }\r
 \r
-  if ((UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > PreAllocatedPages) {\r
+  if ((UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > mPreAllocatedPages) {\r
     //\r
     // If new SMBIOS talbe size exceeds the original pre-allocated page, \r
     // it is time to re-allocate memory (below 4GB).\r
@@ -949,15 +971,16 @@ SmbiosCreateTable (
       //      \r
       FreePages (\r
             (VOID*)(UINTN)EntryPointStructure->TableAddress,\r
-            PreAllocatedPages\r
+            mPreAllocatedPages\r
             );\r
       EntryPointStructure->TableAddress = 0;\r
+      mPreAllocatedPages = 0;\r
     }\r
     \r
     PhysicalAddress = 0xffffffff;\r
     Status = gBS->AllocatePages (\r
                     AllocateMaxAddress,\r
-                    EfiReservedMemoryType,\r
+                    EfiRuntimeServicesData,\r
                     EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength),\r
                     &PhysicalAddress\r
                     );\r
@@ -967,6 +990,7 @@ SmbiosCreateTable (
       return EFI_OUT_OF_RESOURCES;\r
     } else {\r
       EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+      mPreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
     }\r
   }\r
   \r
@@ -1054,8 +1078,11 @@ SmbiosDriverEntryPoint (
   mPrivateData.Smbios.UpdateString      = SmbiosUpdateString;\r
   mPrivateData.Smbios.Remove            = SmbiosRemove;\r
   mPrivateData.Smbios.GetNext           = SmbiosGetNext;\r
-  mPrivateData.Smbios.MajorVersion      = (UINT8) (FixedPcdGet16 (PcdSmbiosVersion) >> 8);\r
-  mPrivateData.Smbios.MinorVersion      = (UINT8) (FixedPcdGet16 (PcdSmbiosVersion) & 0x00ff);\r
+  mPrivateData.Smbios.MajorVersion      = (UINT8) (PcdGet16 (PcdSmbiosVersion) >> 8);\r
+  mPrivateData.Smbios.MinorVersion      = (UINT8) (PcdGet16 (PcdSmbiosVersion) & 0x00ff);\r
+  EntryPointStructureData.MajorVersion  = mPrivateData.Smbios.MajorVersion;\r
+  EntryPointStructureData.MinorVersion  = mPrivateData.Smbios.MinorVersion;\r
+  EntryPointStructureData.SmbiosBcdRevision = (UINT8) ((PcdGet16 (PcdSmbiosVersion) >> 4) & 0xf0) | (UINT8) (PcdGet16 (PcdSmbiosVersion) & 0x0f);\r
 \r
   InitializeListHead (&mPrivateData.DataListHead);\r
   InitializeListHead (&mPrivateData.AllocatedHandleListHead);\r
@@ -1068,7 +1095,7 @@ SmbiosDriverEntryPoint (
   PhysicalAddress = 0xffffffff;\r
   Status = gBS->AllocatePages (\r
                   AllocateMaxAddress,\r
-                  EfiReservedMemoryType,\r
+                  EfiRuntimeServicesData,\r
                   EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
                   &PhysicalAddress\r
                   );\r
@@ -1076,7 +1103,7 @@ SmbiosDriverEntryPoint (
     DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate EntryPointStructure < 4GB\n"));\r
     Status = gBS->AllocatePages (\r
                     AllocateAnyPages,\r
-                    EfiReservedMemoryType,\r
+                    EfiRuntimeServicesData,\r
                     EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
                     &PhysicalAddress\r
                     );\r
@@ -1102,18 +1129,23 @@ SmbiosDriverEntryPoint (
   PhysicalAddress = 0xffffffff;\r
   Status = gBS->AllocatePages (\r
                   AllocateMaxAddress,\r
-                  EfiReservedMemoryType,\r
+                  EfiRuntimeServicesData,\r
                   1,\r
                   &PhysicalAddress\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate SMBIOS table < 4GB\n"));\r
     EntryPointStructure->TableAddress = 0;\r
-    EntryPointStructure->TableLength  = 0;\r
   } else {\r
     EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
-    EntryPointStructure->TableLength  = EFI_PAGES_TO_SIZE (1);\r
+    mPreAllocatedPages = 1;\r
   }\r
+\r
+  //\r
+  // Init TableLength to the length of End-Of-Table structure for SmbiosAdd() called at the first time\r
+  // to check the TableLength limitation.\r
+  //\r
+  EntryPointStructure->TableLength  = sizeof (EFI_SMBIOS_TABLE_END_STRUCTURE);\r
   \r
   //\r
   // Make a new handle and install the protocol\r