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
This commit is contained in:
Elvin Li 2013-12-05 05:30:27 +00:00 committed by li-elvin
parent b4e7b2d2cd
commit b68237300a
5 changed files with 197 additions and 18 deletions

View File

@ -1,6 +1,6 @@
/** @file /** @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 This program and the accompanying materials
are licensed and made available under the terms and conditions 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; 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 Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode
memory. memory.
@ -661,6 +673,98 @@ GetPciInterfaceVersion (
return PciInterfaceVersion; return PciInterfaceVersion;
} }
/**
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. Install Driver to produce Legacy BIOS protocol.
@ -697,6 +801,7 @@ LegacyBiosInstall (
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINT64 Length; UINT64 Length;
UINT8 *SecureBoot; UINT8 *SecureBoot;
EFI_EVENT InstallSmbiosEvent;
// //
// Load this driver's image to memory // Load this driver's image to memory
@ -1009,6 +1114,24 @@ LegacyBiosInstall (
// Save EFI value // Save EFI value
// //
Private->ThunkSeg = (UINT16) (EFI_SEGMENT (IntRedirCode)); 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 // Make a new handle and install the protocol

View File

@ -3,7 +3,7 @@
# #
# This driver installs Legacy Bios Protocol to support CSM module work in EFI system. # 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 # This program and the accompanying materials
# are licensed and made available under the terms and conditions # are licensed and made available under the terms and conditions
@ -103,6 +103,7 @@
[Guids] [Guids]
gEfiDiskInfoIdeInterfaceGuid # ALWAYS_CONSUMED gEfiDiskInfoIdeInterfaceGuid # ALWAYS_CONSUMED
gEfiSmbiosTableGuid # ALWAYS_CONSUMED
gEfiLegacyBiosGuid # ALWAYS_PRODUCED gEfiLegacyBiosGuid # ALWAYS_PRODUCED
[Guids.IA32] [Guids.IA32]

View File

@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <FrameworkDxe.h> #include <FrameworkDxe.h>
#include <IndustryStandard/Pci.h> #include <IndustryStandard/Pci.h>
#include <IndustryStandard/SmBios.h>
#include <Guid/SmBios.h> #include <Guid/SmBios.h>
#include <Guid/Acpi.h> #include <Guid/Acpi.h>

View File

@ -1,6 +1,6 @@
/** @file /** @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 This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -33,6 +33,10 @@ UINT64 mLowWater = 0xffffffffffffffffULL;
extern BBS_TABLE *mBbsTable; extern BBS_TABLE *mBbsTable;
extern VOID *mRuntimeSmbiosEntryPoint;
extern EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint;
extern EFI_PHYSICAL_ADDRESS mStructureTableAddress;
/** /**
Print the BBS Table. Print the BBS Table.
@ -777,6 +781,63 @@ LegacyGetDataOrTable (
return EFI_SUCCESS; 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 Assign drive number to legacy HDD drives prior to booting an EFI
@ -815,7 +876,6 @@ GenericLegacyBoot (
EFI_HANDLE IdeController; EFI_HANDLE IdeController;
UINTN HandleCount; UINTN HandleCount;
EFI_HANDLE *HandleBuffer; EFI_HANDLE *HandleBuffer;
VOID *SmbiosTable;
VOID *AcpiTable; VOID *AcpiTable;
UINTN ShadowAddress; UINTN ShadowAddress;
UINT32 Granularity; UINT32 Granularity;
@ -904,21 +964,15 @@ GenericLegacyBoot (
); );
Private->Legacy16Table->E820Length = (UINT32) CopySize; 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. // 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")); DEBUG ((EFI_D_INFO, "Smbios table is not found!\n"));
} }
EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)SmbiosTable; CreateSmbiosTableInReservedMemory ();
EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint;
AcpiTable = NULL; AcpiTable = NULL;
Status = EfiGetSystemConfigurationTable ( Status = EfiGetSystemConfigurationTable (

View File

@ -981,7 +981,7 @@ SmbiosCreateTable (
PhysicalAddress = 0xffffffff; PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
AllocateMaxAddress, AllocateMaxAddress,
EfiReservedMemoryType, EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength), EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength),
&PhysicalAddress &PhysicalAddress
); );
@ -1093,7 +1093,7 @@ SmbiosDriverEntryPoint (
PhysicalAddress = 0xffffffff; PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
AllocateMaxAddress, AllocateMaxAddress,
EfiReservedMemoryType, EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)), EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),
&PhysicalAddress &PhysicalAddress
); );
@ -1101,7 +1101,7 @@ SmbiosDriverEntryPoint (
DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate EntryPointStructure < 4GB\n")); DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate EntryPointStructure < 4GB\n"));
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
AllocateAnyPages, AllocateAnyPages,
EfiReservedMemoryType, EfiRuntimeServicesData,
EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)), EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),
&PhysicalAddress &PhysicalAddress
); );
@ -1127,7 +1127,7 @@ SmbiosDriverEntryPoint (
PhysicalAddress = 0xffffffff; PhysicalAddress = 0xffffffff;
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
AllocateMaxAddress, AllocateMaxAddress,
EfiReservedMemoryType, EfiRuntimeServicesData,
1, 1,
&PhysicalAddress &PhysicalAddress
); );