diff options
author | Elvin Li <elvin.li@intel.com> | 2013-12-05 05:30:27 +0000 |
---|---|---|
committer | li-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-12-05 05:30:27 +0000 |
commit | b68237300a036c59dcb1231708e64e12fd2f734f (patch) | |
tree | beeddff5337cc875f055b3d916b3c0a6ea8b080c | |
parent | b4e7b2d2cd1f5a5856206d2afaf4da2de5a8adc4 (diff) | |
download | edk2-b68237300a036c59dcb1231708e64e12fd2f734f.zip edk2-b68237300a036c59dcb1231708e64e12fd2f734f.tar.gz edk2-b68237300a036c59dcb1231708e64e12fd2f734f.tar.bz2 |
Following UEFI spec, update SmbiosDxe to use EfiRuntimeServicesData to put SMBIOS table. Update LegacyBiosDxe to move SMBIOS table to reserved memory for backward compatibility.
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
5 files changed, 197 insertions, 18 deletions
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c index 99a76c9..452487b 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c @@ -1,6 +1,6 @@ /** @file
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -29,6 +29,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. //
LEGACY_BIOS_INSTANCE mPrivateData;
+//
+// The SMBIOS table in EfiRuntimeServicesData memory
+//
+VOID *mRuntimeSmbiosEntryPoint = NULL;
+
+//
+// The SMBIOS table in EfiReservedMemoryType memory
+//
+EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint = 0;
+EFI_PHYSICAL_ADDRESS mStructureTableAddress = 0;
+UINTN mStructureTablePages = 0;
+
/**
Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode
memory.
@@ -662,6 +674,98 @@ GetPciInterfaceVersion ( }
/**
+ Callback function to calculate SMBIOS table size, and allocate memory for SMBIOS table.
+ SMBIOS table will be copied into EfiReservedMemoryType memory in legacy boot path.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+InstallSmbiosEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;
+
+ //
+ // Get SMBIOS table from EFI configuration table
+ //
+ Status = EfiGetSystemConfigurationTable (
+ &gEfiSmbiosTableGuid,
+ &mRuntimeSmbiosEntryPoint
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;
+
+ //
+ // Allocate memory for SMBIOS Entry Point Structure.
+ // CSM framework spec requires SMBIOS table below 4GB in EFI_TO_COMPATIBILITY16_BOOT_TABLE.
+ //
+ if (mReserveSmbiosEntryPoint == 0) {
+ //
+ // Entrypoint structure with fixed size is allocated only once.
+ //
+ mReserveSmbiosEntryPoint = SIZE_4GB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength)),
+ &mReserveSmbiosEntryPoint
+ );
+ if (EFI_ERROR (Status)) {
+ mReserveSmbiosEntryPoint = 0;
+ return;
+ }
+ DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Entry Point Structure\n"));
+ }
+
+ if ((mStructureTableAddress != 0) &&
+ (mStructureTablePages < (UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength))) {
+ //
+ // If original buffer is not enough for the new SMBIOS table, free original buffer and re-allocate
+ //
+ gBS->FreePages (mStructureTableAddress, mStructureTablePages);
+ mStructureTableAddress = 0;
+ mStructureTablePages = 0;
+ DEBUG ((EFI_D_INFO, "Original size is not enough. Re-allocate the memory.\n"));
+ }
+
+ if (mStructureTableAddress == 0) {
+ //
+ // Allocate reserved memory below 4GB.
+ // Smbios spec requires the structure table is below 4GB.
+ //
+ mStructureTableAddress = SIZE_4GB - 1;
+ mStructureTablePages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ mStructureTablePages,
+ &mStructureTableAddress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (
+ mReserveSmbiosEntryPoint,
+ EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength))
+ );
+ mReserveSmbiosEntryPoint = 0;
+ mStructureTableAddress = 0;
+ mStructureTablePages = 0;
+ return;
+ }
+ DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Structure Table\n"));
+ }
+}
+
+/**
Install Driver to produce Legacy BIOS protocol.
@param ImageHandle Handle of driver image.
@@ -697,6 +801,7 @@ LegacyBiosInstall ( EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINT64 Length;
UINT8 *SecureBoot;
+ EFI_EVENT InstallSmbiosEvent;
//
// Load this driver's image to memory
@@ -1009,6 +1114,24 @@ LegacyBiosInstall ( // Save EFI value
//
Private->ThunkSeg = (UINT16) (EFI_SEGMENT (IntRedirCode));
+
+ //
+ // Allocate reserved memory for SMBIOS table used in legacy boot if SMBIOS table exists
+ //
+ InstallSmbiosEventCallback (NULL, NULL);
+
+ //
+ // Create callback function to update the size of reserved memory after LegacyBiosDxe starts
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ InstallSmbiosEventCallback,
+ NULL,
+ &gEfiSmbiosTableGuid,
+ &InstallSmbiosEvent
+ );
+ ASSERT_EFI_ERROR (Status);
//
// Make a new handle and install the protocol
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf index a5ad0df..e3084e6 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf @@ -3,7 +3,7 @@ #
# This driver installs Legacy Bios Protocol to support CSM module work in EFI system.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions
@@ -103,6 +103,7 @@ [Guids]
gEfiDiskInfoIdeInterfaceGuid # ALWAYS_CONSUMED
+ gEfiSmbiosTableGuid # ALWAYS_CONSUMED
gEfiLegacyBiosGuid # ALWAYS_PRODUCED
[Guids.IA32]
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h index d60851a..cc893a4 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h @@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <FrameworkDxe.h>
#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/SmBios.h>
#include <Guid/SmBios.h>
#include <Guid/Acpi.h>
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c index dfdac35..bf27605 100644 --- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c +++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c @@ -1,6 +1,6 @@ /** @file
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -33,6 +33,10 @@ UINT64 mLowWater = 0xffffffffffffffffULL; extern BBS_TABLE *mBbsTable;
+extern VOID *mRuntimeSmbiosEntryPoint;
+extern EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint;
+extern EFI_PHYSICAL_ADDRESS mStructureTableAddress;
+
/**
Print the BBS Table.
@@ -777,6 +781,63 @@ LegacyGetDataOrTable ( return EFI_SUCCESS;
}
+/**
+ Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot.
+
+**/
+VOID
+CreateSmbiosTableInReservedMemory (
+ VOID
+ )
+{
+ SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;
+
+ if ((mRuntimeSmbiosEntryPoint == NULL) ||
+ (mReserveSmbiosEntryPoint == 0) ||
+ (mStructureTableAddress == 0)) {
+ return;
+ }
+
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;
+
+ //
+ // Copy SMBIOS Entry Point Structure
+ //
+ CopyMem (
+ (VOID *)(UINTN) mReserveSmbiosEntryPoint,
+ EntryPointStructure,
+ EntryPointStructure->EntryPointLength
+ );
+
+ //
+ // Copy SMBIOS Structure Table into EfiReservedMemoryType memory
+ //
+ CopyMem (
+ (VOID *)(UINTN) mStructureTableAddress,
+ (VOID *)(UINTN) EntryPointStructure->TableAddress,
+ EntryPointStructure->TableLength
+ );
+
+ //
+ // Update TableAddress in Entry Point Structure
+ //
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN) mReserveSmbiosEntryPoint;
+ EntryPointStructure->TableAddress = (UINT32)(UINTN) mStructureTableAddress;
+
+ //
+ // Fixup checksums in the Entry Point Structure
+ //
+ EntryPointStructure->IntermediateChecksum = 0;
+ EntryPointStructure->EntryPointStructureChecksum = 0;
+
+ EntryPointStructure->IntermediateChecksum =
+ CalculateCheckSum8 (
+ (UINT8 *) EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString),
+ EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)
+ );
+ EntryPointStructure->EntryPointStructureChecksum =
+ CalculateCheckSum8 ((UINT8 *) EntryPointStructure, EntryPointStructure->EntryPointLength);
+}
/**
Assign drive number to legacy HDD drives prior to booting an EFI
@@ -815,7 +876,6 @@ GenericLegacyBoot ( EFI_HANDLE IdeController;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
- VOID *SmbiosTable;
VOID *AcpiTable;
UINTN ShadowAddress;
UINT32 Granularity;
@@ -904,21 +964,15 @@ GenericLegacyBoot ( );
Private->Legacy16Table->E820Length = (UINT32) CopySize;
}
- //
- // Get SMBIOS and ACPI table pointers
- //
- SmbiosTable = NULL;
- EfiGetSystemConfigurationTable (
- &gEfiSmbiosTableGuid,
- &SmbiosTable
- );
+
//
// We do not ASSERT if SmbiosTable not found. It is possbile that a platform does not produce SmbiosTable.
//
- if (SmbiosTable == NULL) {
+ if (mReserveSmbiosEntryPoint == 0) {
DEBUG ((EFI_D_INFO, "Smbios table is not found!\n"));
}
- EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)SmbiosTable;
+ CreateSmbiosTableInReservedMemory ();
+ EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint;
AcpiTable = NULL;
Status = EfiGetSystemConfigurationTable (
diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c index 8bf5d44..329bdbf 100644 --- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c +++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c @@ -981,7 +981,7 @@ SmbiosCreateTable ( PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages (
AllocateMaxAddress,
- EfiReservedMemoryType,
+ EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength),
&PhysicalAddress
);
@@ -1093,7 +1093,7 @@ SmbiosDriverEntryPoint ( PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages (
AllocateMaxAddress,
- EfiReservedMemoryType,
+ EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),
&PhysicalAddress
);
@@ -1101,7 +1101,7 @@ SmbiosDriverEntryPoint ( DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate EntryPointStructure < 4GB\n"));
Status = gBS->AllocatePages (
AllocateAnyPages,
- EfiReservedMemoryType,
+ EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),
&PhysicalAddress
);
@@ -1127,7 +1127,7 @@ SmbiosDriverEntryPoint ( PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages (
AllocateMaxAddress,
- EfiReservedMemoryType,
+ EfiRuntimeServicesData,
1,
&PhysicalAddress
);
|