/** @file\r
- This code produces the Smbios protocol. It also responsible for constructing \r
+ This code produces the Smbios protocol. It also responsible for constructing\r
SMBIOS table into system table.\r
- \r
-Copyright (c) 2009 - 2011, 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
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
SMBIOS_INSTANCE mPrivateData;\r
\r
+UINTN mPreAllocatedPages = 0;\r
+UINTN mPre64BitAllocatedPages = 0;\r
+\r
//\r
// Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.\r
//\r
//\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
//\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
//\r
// SmbiosBcdRevision\r
//\r
- 0 \r
+ 0\r
};\r
\r
-\r
-\r
+SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios30EntryPointStructure = NULL;\r
+SMBIOS_TABLE_3_0_ENTRY_POINT Smbios30EntryPointStructureData = {\r
+ //\r
+ // AnchorString _SM3_\r
+ //\r
+ {\r
+ 0x5f,\r
+ 0x53,\r
+ 0x4d,\r
+ 0x33,\r
+ 0x5f,\r
+ },\r
+ //\r
+ // EntryPointStructureChecksum,TO BE FILLED\r
+ //\r
+ 0,\r
+ //\r
+ // EntryPointLength\r
+ //\r
+ 0x18,\r
+ //\r
+ // MajorVersion\r
+ //\r
+ 0,\r
+ //\r
+ // MinorVersion\r
+ //\r
+ 0,\r
+ //\r
+ // DocRev\r
+ //\r
+ 0,\r
+ //\r
+ // EntryPointRevision\r
+ //\r
+ 0x01,\r
+ //\r
+ // Reserved\r
+ //\r
+ 0,\r
+ //\r
+ // TableMaximumSize,TO BE FILLED\r
+ //\r
+ 0,\r
+ //\r
+ // TableAddress,TO BE FILLED\r
+ //\r
+ 0\r
+};\r
/**\r
\r
Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
\r
@retval EFI_SUCCESS Size retured in Size.\r
@retval EFI_INVALID_PARAMETER Input SMBIOS structure mal-formed or Size is NULL.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
)\r
{\r
UINTN FullSize;\r
- UINT8 StrLen;\r
+ UINTN StrLen;\r
+ UINTN MaxLen;\r
INT8* CharInStr;\r
- \r
+\r
if (Size == NULL || NumberOfStrings == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
// look for the two consecutive zeros, check the string limit by the way.\r
//\r
- while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
+ while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
if (*CharInStr == 0) {\r
*Size += 1;\r
CharInStr++;\r
}\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 if (This->MajorVersion < 3) {\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
+ MaxLen = SMBIOS_TABLE_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
+ // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
+ // Locate the end of string as long as possible.\r
//\r
- for (StrLen = 0 ;; StrLen++) {\r
- if (*(CharInStr+StrLen) == 0) {\r
- break;\r
- }\r
+ MaxLen = SMBIOS_3_0_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
\r
@retval TRUE Smbios handle already in use.\r
@retval FALSE Smbios handle is NOT used.\r
- \r
+\r
**/\r
BOOLEAN\r
EFIAPI\r
{\r
LIST_ENTRY *Link;\r
SMBIOS_HANDLE_ENTRY *HandleEntry;\r
- \r
+\r
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
HandleEntry = SMBIOS_HANDLE_ENTRY_FROM_LINK(Link);\r
if (HandleEntry->SmbiosHandle == Handle) {\r
GetMaxSmbiosHandle (\r
IN CONST EFI_SMBIOS_PROTOCOL *This,\r
IN OUT EFI_SMBIOS_HANDLE *MaxHandle\r
- ) \r
+ )\r
{\r
if (This->MajorVersion == 2 && This->MinorVersion == 0) {\r
*MaxHandle = 0xFFFE;\r
\r
@retval EFI_SUCCESS Smbios handle got.\r
@retval EFI_OUT_OF_RESOURCES Smbios handle is NOT available.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
\r
Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
Head = &Private->AllocatedHandleListHead;\r
- for (AvailableHandle = 1; AvailableHandle < MaxSmbiosHandle; AvailableHandle++) {\r
+ for (AvailableHandle = 0; AvailableHandle < MaxSmbiosHandle; AvailableHandle++) {\r
if (!CheckSmbiosHandleExistance(Head, AvailableHandle)) {\r
*Handle = AvailableHandle;\r
return EFI_SUCCESS;\r
@param This The EFI_SMBIOS_PROTOCOL instance.\r
@param ProducerHandle The handle of the controller or driver associated with the SMBIOS information. NULL\r
means no handle.\r
- @param SmbiosHandle On entry, if non-zero, the handle of the SMBIOS record. If zero, then a unique handle\r
- will be assigned to the SMBIOS record. If the SMBIOS handle is already in use\r
+ @param SmbiosHandle On entry, the handle of the SMBIOS record to add. If FFFEh, then a unique handle\r
+ will be assigned to the SMBIOS record. If the SMBIOS handle is already in use,\r
EFI_ALREADY_STARTED is returned and the SMBIOS record is not updated.\r
@param Record The data for the fixed portion of the SMBIOS record. The format of the record is\r
- determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined \r
- by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or \r
+ determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined\r
+ by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or\r
a set of null terminated strings and a null.\r
\r
@retval EFI_SUCCESS Record was added.\r
EFI_SMBIOS_HANDLE MaxSmbiosHandle;\r
SMBIOS_HANDLE_ENTRY *HandleEntry;\r
EFI_SMBIOS_RECORD_HEADER *InternalRecord;\r
- \r
+ BOOLEAN Smbios32BitTable;\r
+ BOOLEAN Smbios64BitTable;\r
+\r
if (SmbiosHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- \r
+\r
Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
//\r
// Check whether SmbiosHandle is already in use\r
//\r
Head = &Private->AllocatedHandleListHead;\r
- if (*SmbiosHandle != 0 && CheckSmbiosHandleExistance(Head, *SmbiosHandle)) {\r
+ if (*SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED && CheckSmbiosHandleExistance(Head, *SmbiosHandle)) {\r
return EFI_ALREADY_STARTED;\r
}\r
\r
//\r
- // when SmbiosHandle is zero, an available handle will be assigned\r
+ // when SmbiosHandle is 0xFFFE, an available handle will be assigned\r
//\r
- if (*SmbiosHandle == 0) {\r
+ if (*SmbiosHandle == SMBIOS_HANDLE_PI_RESERVED) {\r
Status = GetAvailableSmbiosHandle(This, SmbiosHandle);\r
if (EFI_ERROR(Status)) {\r
return Status;\r
return Status;\r
}\r
\r
+ Smbios32BitTable = FALSE;\r
+ Smbios64BitTable = FALSE;\r
+ if ((This->MajorVersion < 0x3) ||\r
+ ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {\r
+ //\r
+ // For SMBIOS 32-bit table, 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. So the max size of 32-bit table should not exceed 65,535 bytes.\r
+ //\r
+ if ((EntryPointStructure != NULL) &&\r
+ (EntryPointStructure->TableLength + StructureSize > SMBIOS_TABLE_MAX_LENGTH)) {\r
+ DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 32-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize));\r
+ } else {\r
+ Smbios32BitTable = TRUE;\r
+ DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 32-bit table\n", Record->Type, StructureSize));\r
+ }\r
+ }\r
+\r
+ //\r
+ // For SMBIOS 3.0, Structure table maximum size in Entry Point structure is DWORD field limited to 0xFFFFFFFF bytes.\r
+ //\r
+ if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {\r
+ //\r
+ // For SMBIOS 64-bit table, Structure table maximum size in SMBIOS 3.0 (64-bit) Entry Point\r
+ // is a DWORD field limited to 0xFFFFFFFF bytes. So the max size of 64-bit table should not exceed 0xFFFFFFFF bytes.\r
+ //\r
+ if ((Smbios30EntryPointStructure != NULL) &&\r
+ (Smbios30EntryPointStructure->TableMaximumSize + StructureSize > SMBIOS_3_0_TABLE_MAX_LENGTH)) {\r
+ DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 64-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 64-bit table\n", Record->Type, StructureSize));\r
+ Smbios64BitTable = TRUE;\r
+ }\r
+ }\r
+\r
+ if ((!Smbios32BitTable) && (!Smbios64BitTable)) {\r
+ //\r
+ // If both 32-bit and 64-bit table are not updated, quit\r
+ //\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
//\r
// Enter into critical section\r
- // \r
+ //\r
Status = EfiAcquireLockOrFail (&Private->DataLock);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
RecordSize = sizeof (EFI_SMBIOS_RECORD_HEADER) + StructureSize;\r
TotalSize = sizeof (EFI_SMBIOS_ENTRY) + RecordSize;\r
\r
SmbiosEntry->Signature = EFI_SMBIOS_ENTRY_SIGNATURE;\r
SmbiosEntry->RecordHeader = InternalRecord;\r
SmbiosEntry->RecordSize = TotalSize;\r
+ SmbiosEntry->Smbios32BitTable = Smbios32BitTable;\r
+ SmbiosEntry->Smbios64BitTable = Smbios64BitTable;\r
InsertTailList (&Private->DataListHead, &SmbiosEntry->Link);\r
\r
CopyMem (Raw, Record, StructureSize);\r
// configuration table, so other UEFI drivers can get SMBIOS table from\r
// configuration table without depending on PI SMBIOS protocol.\r
//\r
- SmbiosTableConstruction ();\r
- \r
+ SmbiosTableConstruction (Smbios32BitTable, Smbios64BitTable);\r
+\r
//\r
// Leave critical section\r
//\r
\r
@retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.\r
@retval EFI_INVALID_PARAMETER SmbiosHandle does not exist.\r
- @retval EFI_UNSUPPORTED String was not added since it's longer than 64 significant characters.\r
+ @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.\r
@retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.\r
\r
**/\r
EFI_SMBIOS_HANDLE MaxSmbiosHandle;\r
EFI_SMBIOS_TABLE_HEADER *Record;\r
EFI_SMBIOS_RECORD_HEADER *InternalRecord;\r
- \r
+\r
//\r
// Check args validity\r
//\r
\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 if (This->MajorVersion < 3) {\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
+ } else {\r
+ if (InputStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH) {\r
+ //\r
+ // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
+ // The input string length should not exceed 0xFFFFFFFF bytes.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
}\r
\r
Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
//\r
// Enter into critical section\r
- // \r
+ //\r
Status = EfiAcquireLockOrFail (&Private->DataLock);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
// Point to unformed string section\r
//\r
StrStart = (CHAR8 *) Record + Record->Length;\r
- \r
+\r
for (StrIndex = 1, TargetStrOffset = 0; StrIndex < *StringNumber; StrStart++, TargetStrOffset++) {\r
//\r
// A string ends in 00h\r
if (*StrStart == 0) {\r
StrIndex++;\r
}\r
- \r
+\r
//\r
// String section ends in double-null (0000h)\r
//\r
if (*StrStart == 0 && *(StrStart + 1) == 0) {\r
EfiReleaseLock (&Private->DataLock);\r
return EFI_NOT_FOUND;\r
- } \r
+ }\r
}\r
\r
if (*StrStart == 0) {\r
StrStart++;\r
TargetStrOffset++;\r
}\r
- \r
+\r
//\r
// Now we get the string target\r
//\r
TargetStrLen = AsciiStrLen(StrStart);\r
if (InputStrLen == TargetStrLen) {\r
- AsciiStrCpy(StrStart, String);\r
+ AsciiStrCpyS(StrStart, TargetStrLen + 1, String);\r
//\r
// Some UEFI drivers (such as network) need some information in SMBIOS table.\r
// Here we create SMBIOS table and publish it in\r
// configuration table, so other UEFI drivers can get SMBIOS table from\r
// configuration table without depending on PI SMBIOS protocol.\r
//\r
- SmbiosTableConstruction ();\r
+ SmbiosTableConstruction (SmbiosEntry->Smbios32BitTable, SmbiosEntry->Smbios64BitTable);\r
EfiReleaseLock (&Private->DataLock);\r
return EFI_SUCCESS;\r
}\r
\r
+ SmbiosEntry->Smbios32BitTable = FALSE;\r
+ SmbiosEntry->Smbios64BitTable = FALSE;\r
+ if ((This->MajorVersion < 0x3) ||\r
+ ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {\r
+ //\r
+ // 32-bit table is produced, check the valid length.\r
+ //\r
+ if ((EntryPointStructure != NULL) &&\r
+ (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
+ DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 32-bit table length\n"));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 32-bit table\n"));\r
+ SmbiosEntry->Smbios32BitTable = TRUE;\r
+ }\r
+ }\r
+\r
+ if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {\r
+ //\r
+ // 64-bit table is produced, check the valid length.\r
+ //\r
+ if ((Smbios30EntryPointStructure != NULL) &&\r
+ (Smbios30EntryPointStructure->TableMaximumSize + InputStrLen - TargetStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH)) {\r
+ DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 64-bit table length\n"));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 64-bit table\n"));\r
+ SmbiosEntry->Smbios64BitTable = TRUE;\r
+ }\r
+ }\r
+\r
+ if ((!SmbiosEntry->Smbios32BitTable) && (!SmbiosEntry->Smbios64BitTable)) {\r
+ EfiReleaseLock (&Private->DataLock);\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
ResizedSmbiosEntry->Signature = EFI_SMBIOS_ENTRY_SIGNATURE;\r
ResizedSmbiosEntry->RecordHeader = InternalRecord;\r
ResizedSmbiosEntry->RecordSize = NewEntrySize;\r
+ ResizedSmbiosEntry->Smbios32BitTable = SmbiosEntry->Smbios32BitTable;\r
+ ResizedSmbiosEntry->Smbios64BitTable = SmbiosEntry->Smbios64BitTable;\r
InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link);\r
\r
//\r
// configuration table, so other UEFI drivers can get SMBIOS table from\r
// configuration table without depending on PI SMBIOS protocol.\r
//\r
- SmbiosTableConstruction ();\r
+ SmbiosTableConstruction (ResizedSmbiosEntry->Smbios32BitTable, ResizedSmbiosEntry->Smbios64BitTable);\r
EfiReleaseLock (&Private->DataLock);\r
return EFI_SUCCESS;\r
}\r
Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
//\r
// Enter into critical section\r
- // \r
+ //\r
Status = EfiAcquireLockOrFail (&Private->DataLock);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
// Remove specified smobios record from DataList\r
//\r
RemoveEntryList(Link);\r
- FreePool(SmbiosEntry);\r
- // \r
+ //\r
// Remove this handle from AllocatedHandleList\r
//\r
Head = &Private->AllocatedHandleListHead;\r
// configuration table, so other UEFI drivers can get SMBIOS table from\r
// configuration table without depending on PI SMBIOS protocol.\r
//\r
- SmbiosTableConstruction ();\r
+ if (SmbiosEntry->Smbios32BitTable) {\r
+ DEBUG ((EFI_D_INFO, "SmbiosRemove: remove from 32-bit table\n"));\r
+ }\r
+ if (SmbiosEntry->Smbios64BitTable) {\r
+ DEBUG ((EFI_D_INFO, "SmbiosRemove: remove from 64-bit table\n"));\r
+ }\r
+ //\r
+ // Update the whole SMBIOS table again based on which table the removed SMBIOS record is in.\r
+ //\r
+ SmbiosTableConstruction (SmbiosEntry->Smbios32BitTable, SmbiosEntry->Smbios64BitTable);\r
+ FreePool(SmbiosEntry);\r
EfiReleaseLock (&Private->DataLock);\r
return EFI_SUCCESS;\r
}\r
//\r
EfiReleaseLock (&Private->DataLock);\r
return EFI_INVALID_PARAMETER;\r
- \r
+\r
}\r
\r
/**\r
\r
@param This The EFI_SMBIOS_PROTOCOL instance.\r
@param SmbiosHandle On entry, points to the previous handle of the SMBIOS record. On exit, points to the\r
- next SMBIOS record handle. If it is zero on entry, then the first SMBIOS record\r
- handle will be returned. If it returns zero on exit, then there are no more SMBIOS records.\r
- @param Type On entry it means return the next SMBIOS record of type Type. If a NULL is passed in \r
+ next SMBIOS record handle. If it is FFFEh on entry, then the first SMBIOS record\r
+ handle will be returned. If it returns FFFEh on exit, then there are no more SMBIOS records.\r
+ @param Type On entry it means return the next SMBIOS record of type Type. If a NULL is passed in\r
this functionally it ignored. Type is not modified by the GetNext() function.\r
@param Record On exit, points to the SMBIOS Record consisting of the formatted area followed by\r
the unformatted area. The unformatted area optionally contains text strings.\r
- @param ProducerHandle On exit, points to the ProducerHandle registered by Add(). If no ProducerHandle was passed into Add() NULL is returned. \r
- If a NULL pointer is passed in no data will be returned \r
- \r
+ @param ProducerHandle On exit, points to the ProducerHandle registered by Add(). If no ProducerHandle was passed into Add() NULL is returned.\r
+ If a NULL pointer is passed in no data will be returned\r
+\r
@retval EFI_SUCCESS SMBIOS record information was successfully returned in Record.\r
@retval EFI_NOT_FOUND The SMBIOS record with SmbiosHandle was the last available record.\r
\r
Head = &Private->DataListHead;\r
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
- SmbiosTableHeader = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1); \r
+ SmbiosTableHeader = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);\r
\r
//\r
- // If SmbiosHandle is zero, the first matched SMBIOS record handle will be returned\r
+ // If SmbiosHandle is 0xFFFE, the first matched SMBIOS record handle will be returned\r
//\r
- if (*SmbiosHandle == 0) {\r
+ if (*SmbiosHandle == SMBIOS_HANDLE_PI_RESERVED) {\r
if ((Type != NULL) && (*Type != SmbiosTableHeader->Type)) {\r
- continue; \r
+ continue;\r
}\r
\r
*SmbiosHandle = SmbiosTableHeader->Handle;\r
\r
if (StartPointFound) {\r
if ((Type != NULL) && (*Type != SmbiosTableHeader->Type)) {\r
- continue; \r
+ continue;\r
}\r
- \r
+\r
*SmbiosHandle = SmbiosTableHeader->Handle;\r
- *Record = SmbiosTableHeader; \r
+ *Record = SmbiosTableHeader;\r
if (ProducerHandle != NULL) {\r
*ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;\r
}\r
\r
- return EFI_SUCCESS; \r
+ return EFI_SUCCESS;\r
}\r
}\r
\r
- *SmbiosHandle = 0;\r
+ *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
return EFI_NOT_FOUND;\r
- \r
+\r
}\r
\r
/**\r
Allow the caller to discover all of the SMBIOS records.\r
\r
@param This The EFI_SMBIOS_PROTOCOL instance.\r
- @param CurrentSmbiosEntry On exit, points to the SMBIOS entry on the list which includes the returned SMBIOS record information. \r
- If *CurrentSmbiosEntry is NULL on entry, then the first SMBIOS entry on the list will be returned. \r
+ @param CurrentSmbiosEntry On exit, points to the SMBIOS entry on the list which includes the returned SMBIOS record information.\r
+ If *CurrentSmbiosEntry is NULL on entry, then the first SMBIOS entry on the list will be returned.\r
@param Record On exit, points to the SMBIOS Record consisting of the formatted area followed by\r
the unformatted area. The unformatted area optionally contains text strings.\r
- \r
+\r
@retval EFI_SUCCESS SMBIOS record information was successfully returned in Record.\r
*CurrentSmbiosEntry points to the SMBIOS entry which includes the returned SMBIOS record information.\r
@retval EFI_NOT_FOUND There is no more SMBIOS entry.\r
//\r
Head = &(*CurrentSmbiosEntry)->Link;\r
}\r
- \r
+\r
Link = Head->ForwardLink;\r
- \r
+\r
if (Link == &Private->DataListHead) {\r
//\r
// If no more SMBIOS entry in the list, return not found.\r
//\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);\r
SmbiosTableHeader = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);\r
- *Record = SmbiosTableHeader; \r
+ *Record = SmbiosTableHeader;\r
*CurrentSmbiosEntry = SmbiosEntry;\r
- return EFI_SUCCESS; \r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
Assembles SMBIOS table from the SMBIOS protocol. Produce Table\r
Entry Point and return the pointer to it.\r
- \r
+\r
@param TableEntryPointStructure On exit, points to the SMBIOS entrypoint structure.\r
- \r
+\r
@retval EFI_SUCCESS Structure created sucessfully.\r
- @retval EFI_NOT_READY Some of The SMBIOS records was not available yet.\r
@retval EFI_OUT_OF_RESOURCES No enough memory.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;\r
EFI_SMBIOS_TABLE_END_STRUCTURE EndStructure;\r
EFI_SMBIOS_ENTRY *CurrentSmbiosEntry;\r
- UINTN PreAllocatedPages;\r
- \r
+\r
Status = EFI_SUCCESS;\r
BufferPointer = NULL;\r
\r
+ if (EntryPointStructure == NULL) {\r
+ //\r
+ // Initialize the EntryPointStructure with initial values.\r
+ // It should be done only once.\r
+ // Allocate memory (below 4GB).\r
+ //\r
+ DEBUG ((EFI_D_INFO, "SmbiosCreateTable: Initialize 32-bit entry point structure\n"));\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
+ PhysicalAddress = 0xffffffff;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
+ &PhysicalAddress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SmbiosCreateTable () could not allocate EntryPointStructure < 4GB\n"));\r
+ Status = gBS->AllocatePages (\r
+ AllocateAnyPages,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
+ &PhysicalAddress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) (UINTN) PhysicalAddress;\r
+\r
+ CopyMem (\r
+ EntryPointStructure,\r
+ &EntryPointStructureData,\r
+ sizeof (SMBIOS_TABLE_ENTRY_POINT)\r
+ );\r
+ }\r
+\r
//\r
// Get Smbios protocol to traverse SMBIOS records.\r
//\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
CurrentSmbiosEntry = NULL;\r
do {\r
Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
- \r
- if (Status == EFI_SUCCESS) {\r
+\r
+ if ((Status == EFI_SUCCESS) && (CurrentSmbiosEntry->Smbios32BitTable)) {\r
GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
//\r
// Record NumberOfSmbiosStructures, TableLength and MaxStructureSize\r
}\r
}\r
} while (!EFI_ERROR(Status));\r
- \r
+\r
//\r
// Create End-Of-Table structure\r
//\r
GetMaxSmbiosHandle(SmbiosProtocol, &SmbiosHandle);\r
- EndStructure.Header.Type = EFI_SMBIOS_TYPE_END_OF_TABLE;\r
+ EndStructure.Header.Type = SMBIOS_TYPE_END_OF_TABLE;\r
EndStructure.Header.Length = (UINT8) sizeof (EFI_SMBIOS_TABLE_HEADER);\r
EndStructure.Header.Handle = SmbiosHandle;\r
EndStructure.Tailing[0] = 0;\r
EntryPointStructure->MaxStructureSize = (UINT16) sizeof (EndStructure);\r
}\r
\r
- if ((UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > PreAllocatedPages) {\r
+ if (EFI_SIZE_TO_PAGES ((UINT32) EntryPointStructure->TableLength) > mPreAllocatedPages) {\r
//\r
- // If new SMBIOS talbe size exceeds the original pre-allocated page, \r
+ // If new SMBIOS table size exceeds the previous allocated page,\r
// it is time to re-allocate memory (below 4GB).\r
- // \r
+ //\r
+ DEBUG ((EFI_D_INFO, "%a() re-allocate SMBIOS 32-bit table\n",\r
+ __FUNCTION__));\r
if (EntryPointStructure->TableAddress != 0) {\r
//\r
- // Free the original pre-allocated page\r
- // \r
+ // Free the previous allocated page\r
+ //\r
FreePages (\r
(VOID*)(UINTN)EntryPointStructure->TableAddress,\r
- PreAllocatedPages\r
+ mPreAllocatedPages\r
);\r
EntryPointStructure->TableAddress = 0;\r
+ mPreAllocatedPages = 0;\r
}\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
return EFI_OUT_OF_RESOURCES;\r
} else {\r
EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+ mPreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
}\r
}\r
- \r
+\r
//\r
// Assemble the tables\r
//\r
do {\r
Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
\r
- if (Status == EFI_SUCCESS) {\r
+ if ((Status == EFI_SUCCESS) && (CurrentSmbiosEntry->Smbios32BitTable)) {\r
GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
CopyMem (BufferPointer, SmbiosRecord, RecordSize);\r
BufferPointer = BufferPointer + RecordSize;\r
}\r
} while (!EFI_ERROR(Status));\r
- \r
+\r
//\r
// Assemble End-Of-Table structure\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 ((UINT8 *) EntryPointStructure + 0x10, EntryPointStructure->EntryPointLength - 0x10);\r
EntryPointStructure->EntryPointStructureChecksum =\r
}\r
\r
/**\r
- Create SMBIOS Table and install it to the System Table.\r
+ Assembles SMBIOS 64-bit table from the SMBIOS protocol. Produce Table\r
+ Entry Point and return the pointer to it.\r
+\r
+ @param TableEntryPointStructure On exit, points to the SMBIOS entrypoint structure.\r
+\r
+ @retval EFI_SUCCESS Structure created sucessfully.\r
+ @retval EFI_OUT_OF_RESOURCES No enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosCreate64BitTable (\r
+ OUT VOID **TableEntryPointStructure\r
+ )\r
+{\r
+ UINT8 *BufferPointer;\r
+ UINTN RecordSize;\r
+ UINTN NumOfStr;\r
+ EFI_STATUS Status;\r
+ EFI_SMBIOS_HANDLE SmbiosHandle;\r
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;\r
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
+ EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;\r
+ EFI_SMBIOS_TABLE_END_STRUCTURE EndStructure;\r
+ EFI_SMBIOS_ENTRY *CurrentSmbiosEntry;\r
+\r
+ Status = EFI_SUCCESS;\r
+ BufferPointer = NULL;\r
+\r
+ if (Smbios30EntryPointStructure == NULL) {\r
+ //\r
+ // Initialize the Smbios30EntryPointStructure with initial values.\r
+ // It should be done only once.\r
+ // Allocate memory at any address.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "SmbiosCreateTable: Initialize 64-bit entry point structure\n"));\r
+ Smbios30EntryPointStructureData.MajorVersion = mPrivateData.Smbios.MajorVersion;\r
+ Smbios30EntryPointStructureData.MinorVersion = mPrivateData.Smbios.MinorVersion;\r
+ Smbios30EntryPointStructureData.DocRev = PcdGet8 (PcdSmbiosDocRev);\r
+ Status = gBS->AllocatePages (\r
+ AllocateAnyPages,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)),\r
+ &PhysicalAddress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SmbiosCreate64BitTable() could not allocate Smbios30EntryPointStructure\n"));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Smbios30EntryPointStructure = (SMBIOS_TABLE_3_0_ENTRY_POINT *) (UINTN) PhysicalAddress;\r
+\r
+ CopyMem (\r
+ Smbios30EntryPointStructure,\r
+ &Smbios30EntryPointStructureData,\r
+ sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT)\r
+ );\r
+ }\r
+\r
+ //\r
+ // Get Smbios protocol to traverse SMBIOS records.\r
+ //\r
+ SmbiosProtocol = &mPrivateData.Smbios;\r
+ Smbios30EntryPointStructure->TableMaximumSize = 0;\r
+\r
+ //\r
+ // Calculate EPS Table Length\r
+ //\r
+ CurrentSmbiosEntry = NULL;\r
+ do {\r
+ Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
+\r
+ if ((Status == EFI_SUCCESS) && (CurrentSmbiosEntry->Smbios64BitTable)) {\r
+ GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
+ //\r
+ // Record TableMaximumSize\r
+ //\r
+ Smbios30EntryPointStructure->TableMaximumSize = (UINT32) (Smbios30EntryPointStructure->TableMaximumSize + RecordSize);\r
+ }\r
+ } while (!EFI_ERROR(Status));\r
+\r
+ //\r
+ // Create End-Of-Table structure\r
+ //\r
+ GetMaxSmbiosHandle(SmbiosProtocol, &SmbiosHandle);\r
+ EndStructure.Header.Type = SMBIOS_TYPE_END_OF_TABLE;\r
+ EndStructure.Header.Length = (UINT8) sizeof (EFI_SMBIOS_TABLE_HEADER);\r
+ EndStructure.Header.Handle = SmbiosHandle;\r
+ EndStructure.Tailing[0] = 0;\r
+ EndStructure.Tailing[1] = 0;\r
+ Smbios30EntryPointStructure->TableMaximumSize = (UINT32) (Smbios30EntryPointStructure->TableMaximumSize + sizeof (EndStructure));\r
+\r
+ if (EFI_SIZE_TO_PAGES (Smbios30EntryPointStructure->TableMaximumSize) > mPre64BitAllocatedPages) {\r
+ //\r
+ // If new SMBIOS table size exceeds the previous allocated page,\r
+ // it is time to re-allocate memory at anywhere.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "%a() re-allocate SMBIOS 64-bit table\n",\r
+ __FUNCTION__));\r
+ if (Smbios30EntryPointStructure->TableAddress != 0) {\r
+ //\r
+ // Free the previous allocated page\r
+ //\r
+ FreePages (\r
+ (VOID*)(UINTN)Smbios30EntryPointStructure->TableAddress,\r
+ mPre64BitAllocatedPages\r
+ );\r
+ Smbios30EntryPointStructure->TableAddress = 0;\r
+ mPre64BitAllocatedPages = 0;\r
+ }\r
+\r
+ Status = gBS->AllocatePages (\r
+ AllocateAnyPages,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (Smbios30EntryPointStructure->TableMaximumSize),\r
+ &PhysicalAddress\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "SmbiosCreateTable() could not allocate SMBIOS 64-bit table\n"));\r
+ Smbios30EntryPointStructure->TableAddress = 0;\r
+ return EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ Smbios30EntryPointStructure->TableAddress = PhysicalAddress;\r
+ mPre64BitAllocatedPages = EFI_SIZE_TO_PAGES (Smbios30EntryPointStructure->TableMaximumSize);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Assemble the tables\r
+ //\r
+ ASSERT (Smbios30EntryPointStructure->TableAddress != 0);\r
+ BufferPointer = (UINT8 *) (UINTN) Smbios30EntryPointStructure->TableAddress;\r
+ CurrentSmbiosEntry = NULL;\r
+ do {\r
+ Status = GetNextSmbiosRecord (SmbiosProtocol, &CurrentSmbiosEntry, &SmbiosRecord);\r
+\r
+ if ((Status == EFI_SUCCESS) && (CurrentSmbiosEntry->Smbios64BitTable)) {\r
+ //\r
+ // This record can be added to 64-bit table\r
+ //\r
+ GetSmbiosStructureSize(SmbiosProtocol, SmbiosRecord, &RecordSize, &NumOfStr);\r
+ CopyMem (BufferPointer, SmbiosRecord, RecordSize);\r
+ BufferPointer = BufferPointer + RecordSize;\r
+ }\r
+ } while (!EFI_ERROR(Status));\r
+\r
+ //\r
+ // Assemble End-Of-Table structure\r
+ //\r
+ CopyMem (BufferPointer, &EndStructure, sizeof (EndStructure));\r
+\r
+ //\r
+ // Fixup checksums in the Entry Point Structure\r
+ //\r
+ Smbios30EntryPointStructure->EntryPointStructureChecksum = 0;\r
+ Smbios30EntryPointStructure->EntryPointStructureChecksum =\r
+ CalculateCheckSum8 ((UINT8 *) Smbios30EntryPointStructure, Smbios30EntryPointStructure->EntryPointLength);\r
+\r
+ //\r
+ // Returns the pointer\r
+ //\r
+ *TableEntryPointStructure = Smbios30EntryPointStructure;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Create Smbios Table and installs the Smbios Table to the System Table.\r
+\r
+ @param Smbios32BitTable The flag to update 32-bit table.\r
+ @param Smbios64BitTable The flag to update 64-bit table.\r
+\r
**/\r
VOID\r
EFIAPI\r
SmbiosTableConstruction (\r
- VOID\r
+ BOOLEAN Smbios32BitTable,\r
+ BOOLEAN Smbios64BitTable\r
)\r
{\r
UINT8 *Eps;\r
+ UINT8 *Eps64Bit;\r
EFI_STATUS Status;\r
\r
- Status = SmbiosCreateTable ((VOID **) &Eps);\r
- if (!EFI_ERROR (Status)) {\r
- gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, Eps);\r
+ if (Smbios32BitTable) {\r
+ Status = SmbiosCreateTable ((VOID **) &Eps);\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, Eps);\r
+ }\r
+ }\r
+\r
+ if (Smbios64BitTable) {\r
+ Status = SmbiosCreate64BitTable ((VOID **) &Eps64Bit);\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->InstallConfigurationTable (&gEfiSmbios3TableGuid, Eps64Bit);\r
+ }\r
}\r
}\r
\r
/**\r
\r
- Driver to produce Smbios protocol and pre-allocate 1 page for the final SMBIOS table. \r
+ Driver to produce Smbios protocol and pre-allocate 1 page for the final SMBIOS table.\r
\r
@param ImageHandle Module's image handle\r
@param SystemTable Pointer of EFI_SYSTEM_TABLE\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
\r
mPrivateData.Signature = SMBIOS_INSTANCE_SIGNATURE;\r
mPrivateData.Smbios.Add = SmbiosAdd;\r
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
\r
InitializeListHead (&mPrivateData.DataListHead);\r
InitializeListHead (&mPrivateData.AllocatedHandleListHead);\r
EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);\r
\r
- //\r
- // Initialize the EntryPointStructure with initial values.\r
- // Allocate memory (below 4GB).\r
- //\r
- PhysicalAddress = 0xffffffff;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiReservedMemoryType,\r
- EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
- &PhysicalAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate EntryPointStructure < 4GB\n"));\r
- Status = gBS->AllocatePages (\r
- AllocateAnyPages,\r
- EfiReservedMemoryType,\r
- EFI_SIZE_TO_PAGES (sizeof (SMBIOS_TABLE_ENTRY_POINT)),\r
- &PhysicalAddress\r
- );\r
- if (EFI_ERROR (Status)) { \r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) (UINTN) PhysicalAddress;\r
- \r
- CopyMem (\r
- EntryPointStructure,\r
- &EntryPointStructureData,\r
- sizeof (SMBIOS_TABLE_ENTRY_POINT)\r
- );\r
-\r
- //\r
- // Pre-allocate 1 page for SMBIOS table below 4GB.\r
- // SMBIOS table will be updated when new SMBIOS type is added or \r
- // existing SMBIOS type is updated. If the total size of SMBIOS table exceeds 1 page,\r
- // we will re-allocate new memory when creating whole SMBIOS table.\r
- //\r
- PhysicalAddress = 0xffffffff;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiReservedMemoryType,\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
- }\r
- \r
//\r
// Make a new handle and install the protocol\r
//\r