/**@file\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. 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
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
Module Name:\r
\r
\r
#include "MiscSubclassDriver.h"\r
\r
+EFI_HII_HANDLE mHiiHandle;\r
+\r
+/**\r
+ This is the standard EFI driver point that detects whether there is a\r
+ MemoryConfigurationData Variable and, if so, reports memory configuration info\r
+ to the DataHub.\r
\r
-extern UINT8 MiscSubclassStrings[];\r
+ @param ImageHandle Handle for the image of this driver\r
+ @param SystemTable Pointer to the EFI System Table\r
\r
+ @return EFI_SUCCESS if the data is successfully reported\r
+ @return EFI_NOT_FOUND if the HOB list could not be located.\r
\r
-//\r
-//\r
-//\r
+**/\r
EFI_STATUS\r
-LogRecordDataToDataHub (\r
- EFI_DATA_HUB_PROTOCOL *DataHub,\r
- UINT32 RecordType,\r
- UINT32 RecordLen,\r
- VOID *RecordData\r
+LogMemorySmbiosRecord (\r
+ VOID\r
)\r
-/*++\r
-Description:\r
-\r
-Parameters:\r
-\r
- DataHub\r
- %%TBD\r
-\r
- RecordType\r
- %%TBD\r
-\r
- RecordLen\r
- %%TBD\r
-\r
- RecordData\r
- %%TBD\r
-\r
-Returns:\r
-\r
- EFI_INVALID_PARAMETER\r
-\r
- EFI_SUCCESS\r
-\r
- Other Data Hub errors\r
-\r
---*/\r
{\r
- EFI_MISC_SUBCLASS_DRIVER_DATA MiscSubclass;\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ UINT64 TotalMemorySize;\r
+ UINT8 NumSlots;\r
+ SMBIOS_TABLE_TYPE19 *Type19Record;\r
+ EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;\r
+ EFI_SMBIOS_PROTOCOL *Smbios;\r
+ CHAR16 *Nt32MemString;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ NumSlots = 1;\r
\r
//\r
- // Do nothing if data parameters are not valid.\r
+ // Process Memory String in form size!size ...\r
+ // So 64!64 is 128 MB\r
//\r
- if (RecordLen == 0 || RecordData == NULL) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "RecordLen == %d RecordData == %xh\n",\r
- RecordLen,\r
- RecordData)\r
- );\r
-\r
- return EFI_INVALID_PARAMETER;\r
+ Nt32MemString = PcdGetPtr (PcdWinNtMemorySize);\r
+ for (TotalMemorySize = 0; *Nt32MemString != '\0';) {\r
+ TotalMemorySize += StrDecimalToUint64 (Nt32MemString);\r
+ while (*Nt32MemString != '\0') {\r
+ if (*Nt32MemString == '!') {\r
+ Nt32MemString++; \r
+ break;\r
+ }\r
+ Nt32MemString++;\r
+ }\r
}\r
+\r
+ //\r
+ // Convert Total Memory Size to based on KiloByte\r
//\r
- // Assemble Data Hub record.\r
+ TotalMemorySize = LShiftU64 (TotalMemorySize, 20);\r
//\r
- MiscSubclass.Header.Version = EFI_MISC_SUBCLASS_VERSION;\r
- MiscSubclass.Header.HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);\r
- MiscSubclass.Header.Instance = 1;\r
- MiscSubclass.Header.SubInstance = 1;\r
- MiscSubclass.Header.RecordType = RecordType;\r
-\r
- CopyMem (\r
- &MiscSubclass.Record,\r
- RecordData,\r
- RecordLen\r
- );\r
+ // Generate Memory Array Mapped Address info\r
+ //\r
+ Type19Record = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE19) + 2);\r
+ Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;\r
+ Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);\r
+ Type19Record->Hdr.Handle = 0;\r
+ Type19Record->StartingAddress = 0;\r
+ Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;\r
+ Type19Record->MemoryArrayHandle = 0;\r
+ Type19Record->PartitionWidth = (UINT8)(NumSlots); \r
\r
//\r
- // Log Data Hub record.\r
+ // Generate Memory Array Mapped Address info (TYPE 19)\r
//\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiMiscSubClassGuid,\r
- &gEfiMiscSubClassGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- &MiscSubclass,\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + RecordLen\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + RecordLen,\r
- Status)\r
- );\r
- }\r
+ Status = AddSmbiosRecord (Smbios, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);\r
+\r
+ FreePool(Type19Record);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
return Status;\r
}\r
\r
--*/\r
{\r
- EFI_MISC_SUBCLASS_DRIVER_DATA RecordData;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- BOOLEAN LogRecordData;\r
- EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData; \r
- UINT64 TotalMemorySize;\r
- CHAR16 *Nt32MemString;\r
+ UINTN Index;\r
+ EFI_STATUS EfiStatus;\r
+ EFI_SMBIOS_PROTOCOL *Smbios; \r
\r
+ EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);\r
\r
- //\r
- // Initialize constant portion of subclass header.\r
- //\r
- RecordData.Header.Version = EFI_MISC_SUBCLASS_VERSION;\r
- RecordData.Header.HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);\r
- RecordData.Header.Instance = 1;\r
- RecordData.Header.SubInstance = 1;\r
-\r
- //\r
- // Locate data hub protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Could not locate DataHub protocol. %r\n", Status));\r
- return Status;\r
- } else if (DataHub == NULL) {\r
- DEBUG ((EFI_D_ERROR, "LocateProtocol(DataHub) returned NULL pointer!\n"));\r
- return EFI_DEVICE_ERROR;\r
+ if (EFI_ERROR(EfiStatus)) {\r
+ DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol. %r\n", EfiStatus));\r
+ return EfiStatus;\r
}\r
- //\r
- // Add our default strings to the HII database. They will be modified later.\r
- //\r
- HiiLibAddPackages (1, &gEfiMiscSubClassGuid, NULL, &HiiHandle, MiscSubclassStrings);\r
\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Could not log default strings to Hii. %r\n", Status));\r
- return Status;\r
- }\r
- //\r
- //\r
- //\r
- for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {\r
- //\r
- // Stupidity check! Do nothing if RecordLen is zero.\r
- // %%TBD - Should this be an error or a mechanism for ignoring\r
- // records in the Data Table?\r
- //\r
- if (mMiscSubclassDataTable[Index].RecordLen == 0) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "mMiscSubclassDataTable[%d].RecordLen == 0\n",\r
- Index)\r
- );\r
+ mHiiHandle = HiiAddPackages (\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ MiscSubclassStrings,\r
+ NULL\r
+ );\r
+ ASSERT (mHiiHandle != NULL);\r
\r
- continue;\r
- }\r
+ for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {\r
//\r
- // Initialize per-record portion of subclass header and\r
- // copy static data into data portion of subclass record.\r
+ // If the entry have a function pointer, just log the data.\r
//\r
- RecordData.Header.RecordType = mMiscSubclassDataTable[Index].RecordType;\r
-\r
- if (mMiscSubclassDataTable[Index].RecordData == NULL) {\r
- ZeroMem (\r
- &RecordData.Record,\r
- mMiscSubclassDataTable[Index].RecordLen\r
- );\r
- } else {\r
- CopyMem (\r
- &RecordData.Record,\r
+ if (mMiscSubclassDataTable[Index].Function != NULL) {\r
+ EfiStatus = (*mMiscSubclassDataTable[Index].Function)(\r
mMiscSubclassDataTable[Index].RecordData,\r
- mMiscSubclassDataTable[Index].RecordLen\r
+ Smbios\r
);\r
- }\r
- //\r
- // If the entry does not have a function pointer, just log the data.\r
- //\r
- if (mMiscSubclassDataTable[Index].Function == NULL) {\r
- //\r
- // Log RecordData to Data Hub.\r
- //\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiMiscSubClassGuid,\r
- &gEfiMiscSubClassGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- &RecordData,\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,\r
- Status)\r
- );\r
- }\r
\r
- continue;\r
- }\r
- //\r
- // The entry has a valid function pointer.\r
- // Keep calling the function and logging data until there\r
- // is no more data to log.\r
- //\r
- for (;;) {\r
- Status = (*mMiscSubclassDataTable[Index].Function)(mMiscSubclassDataTable[Index].RecordType, &mMiscSubclassDataTable[Index].RecordLen, &RecordData.Record, &LogRecordData);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (!LogRecordData) {\r
- break;\r
- }\r
-\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiMiscSubClassGuid,\r
- &gEfiMiscSubClassGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- &RecordData,\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,\r
- Status)\r
- );\r
+ if (EFI_ERROR(EfiStatus)) {\r
+ DEBUG((EFI_D_ERROR, "Misc smbios store error. Index=%d, ReturnStatus=%r\n", Index, EfiStatus));\r
+ return EfiStatus;\r
}\r
}\r
}\r
\r
- \r
- //\r
- // Log Memory Size info based on PCD setting.\r
- //\r
- MemorySubClassData.Header.Instance = 1;\r
- MemorySubClassData.Header.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r
- MemorySubClassData.Header.RecordType = EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER;\r
-\r
//\r
- // Process Memory String in form size!size ...\r
- // So 64!64 is 128 MB\r
+ // Log Memory SMBIOS Record\r
//\r
- Nt32MemString = PcdGetPtr (PcdWinNtMemorySize);\r
- for (TotalMemorySize = 0; *Nt32MemString != '\0';) {\r
- TotalMemorySize += StrDecimalToUint64 (Nt32MemString);\r
- while (*Nt32MemString != '\0') {\r
- if (*Nt32MemString == '!') {\r
- Nt32MemString++; \r
- break;\r
- }\r
- Nt32MemString++;\r
- }\r
- }\r
+ EfiStatus = LogMemorySmbiosRecord();\r
+ return EfiStatus;\r
+}\r
\r
- MemorySubClassData.Record.ArrayStartAddress.MemoryArrayStartAddress = 0;\r
- MemorySubClassData.Record.ArrayStartAddress.MemoryArrayEndAddress = LShiftU64 (TotalMemorySize, 20) - 1;\r
- MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.ProducerName = gEfiMemoryProducerGuid;\r
- MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.Instance = 1;\r
- MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r
- MemorySubClassData.Record.ArrayStartAddress.MemoryArrayPartitionWidth = 0;\r
+/**\r
+ Add an SMBIOS record.\r
\r
- //\r
- // Store memory size data record to data hub.\r
- //\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiMemorySubClassGuid,\r
- &gEfiMemoryProducerGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- &MemorySubClassData,\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS_DATA)\r
- );\r
+ @param Smbios The EFI_SMBIOS_PROTOCOL instance.\r
+ @param SmbiosHandle A unique handle will be assigned to the SMBIOS record.\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
+ a set of null terminated strings and a null.\r
\r
+ @retval EFI_SUCCESS Record was added.\r
+ @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources.\r
\r
- return EFI_SUCCESS;\r
+**/\r
+EFI_STATUS\r
+AddSmbiosRecord (\r
+ IN EFI_SMBIOS_PROTOCOL *Smbios,\r
+ OUT EFI_SMBIOS_HANDLE *SmbiosHandle,\r
+ IN EFI_SMBIOS_TABLE_HEADER *Record\r
+ )\r
+{\r
+ *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+ return Smbios->Add (\r
+ Smbios,\r
+ NULL,\r
+ SmbiosHandle,\r
+ Record\r
+ );\r
}\r
\r
-\r