]> xenbits.xensource.com Git - people/liuw/ovmf.git/commitdiff
Following UEFI spec, update SmbiosDxe to use EfiRuntimeServicesData to put SMBIOS...
authorElvin Li <elvin.li@intel.com>
Thu, 5 Dec 2013 05:30:27 +0000 (05:30 +0000)
committerli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 5 Dec 2013 05:30:27 +0000 (05:30 +0000)
Signed-off-by: Elvin Li <elvin.li@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14932 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c

index 99a76c9f21acdd7b12f340621615c91122af8104..452487b66c3c6e0f5b6a1113370bbd3479b32f58 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -29,6 +29,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 LEGACY_BIOS_INSTANCE  mPrivateData;\r
 \r
+//\r
+// The SMBIOS table in EfiRuntimeServicesData memory\r
+//\r
+VOID                  *mRuntimeSmbiosEntryPoint = NULL;\r
+\r
+//\r
+// The SMBIOS table in EfiReservedMemoryType memory\r
+//\r
+EFI_PHYSICAL_ADDRESS  mReserveSmbiosEntryPoint = 0;\r
+EFI_PHYSICAL_ADDRESS  mStructureTableAddress   = 0;\r
+UINTN                 mStructureTablePages     = 0;\r
+\r
 /**\r
   Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode\r
   memory.\r
@@ -661,6 +673,98 @@ GetPciInterfaceVersion (
   return PciInterfaceVersion;\r
 }\r
 \r
+/**\r
+  Callback function to calculate SMBIOS table size, and allocate memory for SMBIOS table.\r
+  SMBIOS table will be copied into EfiReservedMemoryType memory in legacy boot path.\r
+\r
+  @param  Event                 Event whose notification function is being invoked.\r
+  @param  Context               The pointer to the notification function's context,\r
+                                which is implementation-dependent.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InstallSmbiosEventCallback (\r
+  IN EFI_EVENT                Event,\r
+  IN VOID                     *Context\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  SMBIOS_TABLE_ENTRY_POINT    *EntryPointStructure;\r
+  \r
+  //\r
+  // Get SMBIOS table from EFI configuration table\r
+  //\r
+  Status = EfiGetSystemConfigurationTable (\r
+            &gEfiSmbiosTableGuid,\r
+            &mRuntimeSmbiosEntryPoint\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  \r
+  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;\r
+\r
+  //\r
+  // Allocate memory for SMBIOS Entry Point Structure.\r
+  // CSM framework spec requires SMBIOS table below 4GB in EFI_TO_COMPATIBILITY16_BOOT_TABLE.\r
+  //\r
+  if (mReserveSmbiosEntryPoint == 0) {\r
+    //\r
+    // Entrypoint structure with fixed size is allocated only once.\r
+    //\r
+    mReserveSmbiosEntryPoint = SIZE_4GB - 1;\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiReservedMemoryType,\r
+                    EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength)),\r
+                    &mReserveSmbiosEntryPoint\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      mReserveSmbiosEntryPoint = 0;\r
+      return;\r
+    }\r
+    DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Entry Point Structure\n"));\r
+  }\r
+  \r
+  if ((mStructureTableAddress != 0) && \r
+      (mStructureTablePages < (UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength))) {\r
+    //\r
+    // If original buffer is not enough for the new SMBIOS table, free original buffer and re-allocate\r
+    //\r
+    gBS->FreePages (mStructureTableAddress, mStructureTablePages);\r
+    mStructureTableAddress = 0;\r
+    mStructureTablePages   = 0;\r
+    DEBUG ((EFI_D_INFO, "Original size is not enough. Re-allocate the memory.\n"));\r
+  }\r
+  \r
+  if (mStructureTableAddress == 0) {\r
+    //\r
+    // Allocate reserved memory below 4GB.\r
+    // Smbios spec requires the structure table is below 4GB.\r
+    //\r
+    mStructureTableAddress = SIZE_4GB - 1;\r
+    mStructureTablePages   = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiReservedMemoryType,\r
+                    mStructureTablePages,\r
+                    &mStructureTableAddress\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePages (\r
+        mReserveSmbiosEntryPoint, \r
+        EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength))\r
+        );\r
+      mReserveSmbiosEntryPoint = 0;\r
+      mStructureTableAddress   = 0;\r
+      mStructureTablePages     = 0;\r
+      return;\r
+    }\r
+    DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Structure Table\n"));\r
+  }\r
+}\r
+\r
 /**\r
   Install Driver to produce Legacy BIOS protocol.\r
 \r
@@ -697,6 +801,7 @@ LegacyBiosInstall (
   EFI_GCD_MEMORY_SPACE_DESCRIPTOR    Descriptor;\r
   UINT64                             Length;\r
   UINT8                              *SecureBoot;\r
+  EFI_EVENT                          InstallSmbiosEvent;\r
 \r
   //\r
   // Load this driver's image to memory\r
@@ -1009,6 +1114,24 @@ LegacyBiosInstall (
   // Save EFI value\r
   //\r
   Private->ThunkSeg = (UINT16) (EFI_SEGMENT (IntRedirCode));\r
+  \r
+  //\r
+  // Allocate reserved memory for SMBIOS table used in legacy boot if SMBIOS table exists\r
+  //\r
+  InstallSmbiosEventCallback (NULL, NULL);\r
+\r
+  //\r
+  // Create callback function to update the size of reserved memory after LegacyBiosDxe starts\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  InstallSmbiosEventCallback,\r
+                  NULL,\r
+                  &gEfiSmbiosTableGuid,\r
+                  &InstallSmbiosEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);  \r
 \r
   //\r
   // Make a new handle and install the protocol\r
index a5ad0dfd26e0d278cc4a364fd42ae97bbb724ce2..e3084e601f196ec1ebceb7fec30f82bb44191afb 100644 (file)
@@ -3,7 +3,7 @@
 #\r
 # This driver installs Legacy Bios Protocol to support CSM module work in EFI system.\r
 #\r
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions\r
 \r
 [Guids]\r
   gEfiDiskInfoIdeInterfaceGuid                  # ALWAYS_CONSUMED\r
+  gEfiSmbiosTableGuid                           # ALWAYS_CONSUMED\r
   gEfiLegacyBiosGuid                            # ALWAYS_PRODUCED\r
 \r
 [Guids.IA32]\r
index d60851a42cff65f82fc075d0d58306ff0f094f4c..cc893a49a77030297e30514cf7b13162c31f356d 100644 (file)
@@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <FrameworkDxe.h>\r
 #include <IndustryStandard/Pci.h>\r
+#include <IndustryStandard/SmBios.h>\r
 \r
 #include <Guid/SmBios.h>\r
 #include <Guid/Acpi.h>\r
index dfdac356cfb89039e77108d261e04bdc831a84d4..bf27605504423229493d2d0cb2598d12e8dc9c2e 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -33,6 +33,10 @@ UINT64              mLowWater           = 0xffffffffffffffffULL;
 \r
 extern BBS_TABLE           *mBbsTable;\r
 \r
+extern VOID                  *mRuntimeSmbiosEntryPoint;\r
+extern EFI_PHYSICAL_ADDRESS  mReserveSmbiosEntryPoint;\r
+extern EFI_PHYSICAL_ADDRESS  mStructureTableAddress;\r
+\r
 /**\r
   Print the BBS Table.\r
 \r
@@ -777,6 +781,63 @@ LegacyGetDataOrTable (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot.\r
+\r
+**/\r
+VOID\r
+CreateSmbiosTableInReservedMemory (\r
+  VOID\r
+  )\r
+{\r
+  SMBIOS_TABLE_ENTRY_POINT    *EntryPointStructure;\r
+  \r
+  if ((mRuntimeSmbiosEntryPoint == NULL) || \r
+      (mReserveSmbiosEntryPoint == 0) || \r
+      (mStructureTableAddress == 0)) {\r
+    return;\r
+  }\r
+  \r
+  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;\r
+  \r
+  //\r
+  // Copy SMBIOS Entry Point Structure\r
+  //\r
+  CopyMem (\r
+    (VOID *)(UINTN) mReserveSmbiosEntryPoint,\r
+    EntryPointStructure,\r
+    EntryPointStructure->EntryPointLength\r
+  );\r
+  \r
+  //\r
+  // Copy SMBIOS Structure Table into EfiReservedMemoryType memory\r
+  //\r
+  CopyMem (\r
+    (VOID *)(UINTN) mStructureTableAddress,\r
+    (VOID *)(UINTN) EntryPointStructure->TableAddress,\r
+    EntryPointStructure->TableLength\r
+  );\r
+  \r
+  //\r
+  // Update TableAddress in Entry Point Structure\r
+  //\r
+  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN) mReserveSmbiosEntryPoint;\r
+  EntryPointStructure->TableAddress = (UINT32)(UINTN) mStructureTableAddress;\r
+  \r
+  //\r
+  // Fixup checksums in the Entry Point Structure\r
+  //\r
+  EntryPointStructure->IntermediateChecksum = 0;\r
+  EntryPointStructure->EntryPointStructureChecksum = 0;\r
+\r
+  EntryPointStructure->IntermediateChecksum = \r
+    CalculateCheckSum8 (\r
+      (UINT8 *) EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString), \r
+      EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)\r
+      );\r
+  EntryPointStructure->EntryPointStructureChecksum =\r
+    CalculateCheckSum8 ((UINT8 *) EntryPointStructure, EntryPointStructure->EntryPointLength);\r
+}\r
 \r
 /**\r
   Assign drive number to legacy HDD drives prior to booting an EFI\r
@@ -815,7 +876,6 @@ GenericLegacyBoot (
   EFI_HANDLE                        IdeController;\r
   UINTN                             HandleCount;\r
   EFI_HANDLE                        *HandleBuffer;\r
-  VOID                              *SmbiosTable;\r
   VOID                              *AcpiTable;\r
   UINTN                             ShadowAddress;\r
   UINT32                            Granularity;\r
@@ -904,21 +964,15 @@ GenericLegacyBoot (
       );\r
     Private->Legacy16Table->E820Length = (UINT32) CopySize;\r
   }\r
-  //\r
-  // Get SMBIOS and ACPI table pointers\r
-  //\r
-  SmbiosTable = NULL;\r
-  EfiGetSystemConfigurationTable (\r
-    &gEfiSmbiosTableGuid,\r
-    &SmbiosTable\r
-    );\r
+\r
   //\r
   // We do not ASSERT if SmbiosTable not found. It is possbile that a platform does not produce SmbiosTable.\r
   //\r
-  if (SmbiosTable == NULL) {\r
+  if (mReserveSmbiosEntryPoint == 0) {\r
     DEBUG ((EFI_D_INFO, "Smbios table is not found!\n"));\r
   }\r
-  EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)SmbiosTable;\r
+  CreateSmbiosTableInReservedMemory ();\r
+  EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint;\r
 \r
   AcpiTable = NULL;\r
   Status = EfiGetSystemConfigurationTable (\r
index 8bf5d443a192ac74a885cda539012c694214da09..329bdbfc497ac4de3a5fc4757476366a07a10e11 100644 (file)
@@ -981,7 +981,7 @@ SmbiosCreateTable (
     PhysicalAddress = 0xffffffff;\r
     Status = gBS->AllocatePages (\r
                     AllocateMaxAddress,\r
-                    EfiReservedMemoryType,\r
+                    EfiRuntimeServicesData,\r
                     EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength),\r
                     &PhysicalAddress\r
                     );\r
@@ -1093,7 +1093,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
@@ -1101,7 +1101,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
@@ -1127,7 +1127,7 @@ SmbiosDriverEntryPoint (
   PhysicalAddress = 0xffffffff;\r
   Status = gBS->AllocatePages (\r
                   AllocateMaxAddress,\r
-                  EfiReservedMemoryType,\r
+                  EfiRuntimeServicesData,\r
                   1,\r
                   &PhysicalAddress\r
                   );\r