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