+++ /dev/null
-/*++\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
-\r
-Module Name:\r
-\r
- MiscSubclassDriverEntryPoint.c\r
-\r
-Abstract:\r
-\r
- This driver parses the mMiscSubclassDataTable structure and reports\r
- any generated data to the DataHub.\r
-\r
---*/\r
-\r
-#include "MiscSubclassDriver.h"\r
-\r
-\r
-extern UINT8 MiscSubclassStrings[];\r
-\r
-VOID\r
-EFIAPI\r
-WinNtIoProtocolNotifyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\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
- )\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 EfiStatus;\r
-\r
- //\r
- // Do nothing if data parameters are not valid.\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
- }\r
- //\r
- // Assemble Data Hub record.\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
-\r
- //\r
- // Log Data Hub record.\r
- //\r
- EfiStatus = 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 (EfiStatus)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + RecordLen,\r
- EfiStatus)\r
- );\r
- }\r
-\r
- return EfiStatus;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-MiscSubclassDriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-Description:\r
-\r
- Standard EFI driver point. This driver parses the mMiscSubclassDataTable\r
- structure and reports any generated data to the DataHub.\r
-\r
-Arguments:\r
-\r
- ImageHandle\r
- Handle for the image of this driver\r
-\r
- SystemTable\r
- Pointer to the EFI System Table\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- The data was successfully reported to the Data Hub.\r
-\r
---*/\r
-{\r
- EFI_MISC_SUBCLASS_DRIVER_DATA RecordData;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- EFI_HII_PROTOCOL *Hii;\r
- EFI_HII_PACKAGES *PackageList;\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_STATUS EfiStatus;\r
- UINTN Index;\r
- BOOLEAN LogRecordData;\r
- EFI_EVENT Event;\r
- VOID *Registration;\r
-\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
- EfiStatus = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);\r
-\r
- if (EFI_ERROR (EfiStatus)) {\r
- DEBUG ((EFI_D_ERROR, "Could not locate DataHub protocol. %r\n", EfiStatus));\r
- return EfiStatus;\r
- } else if (DataHub == NULL) {\r
- DEBUG ((EFI_D_ERROR, "LocateProtocol(DataHub) returned NULL pointer!\n"));\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Locate hii protocol.\r
- //\r
- EfiStatus = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);\r
-\r
- if (EFI_ERROR (EfiStatus)) {\r
- DEBUG ((EFI_D_ERROR, "Could not locate Hii protocol. %r\n", EfiStatus));\r
- return EfiStatus;\r
- } else if (Hii == NULL) {\r
- DEBUG ((EFI_D_ERROR, "LocateProtocol(Hii) returned NULL pointer!\n"));\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Add our default strings to the HII database. They will be modified later.\r
- //\r
- PackageList = PreparePackages (1, &gEfiMiscSubClassGuid, MiscSubclassStrings);\r
- EfiStatus = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
- FreePool (PackageList);\r
-\r
- if (EFI_ERROR (EfiStatus)) {\r
- DEBUG ((EFI_D_ERROR, "Could not log default strings to Hii. %r\n", EfiStatus));\r
- return EfiStatus;\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
-\r
- continue;\r
- }\r
- //\r
- // Initialize per-record portion of subclass header and\r
- // copy static data into data portion of subclass record.\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
- mMiscSubclassDataTable[Index].RecordData,\r
- mMiscSubclassDataTable[Index].RecordLen\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
- EfiStatus = 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 (EfiStatus)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,\r
- EfiStatus)\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
- //\r
- //\r
- //\r
- EfiStatus = (*mMiscSubclassDataTable[Index].Function)\r
- (\r
- mMiscSubclassDataTable[Index].RecordType, &mMiscSubclassDataTable[Index].RecordLen, &RecordData.Record, &\r
- LogRecordData\r
- );\r
-\r
- //\r
- //\r
- //\r
- if (EFI_ERROR (EfiStatus)) {\r
- break;\r
- }\r
-\r
- if (!LogRecordData) {\r
- break;\r
- }\r
- //\r
- //\r
- //\r
- EfiStatus = 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 (EfiStatus)) {\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- "LogData(%d bytes) == %r\n",\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,\r
- EfiStatus)\r
- );\r
- }\r
- }\r
- }\r
- //\r
- // Install notify function to fetch memory data through WinNtIo protocol and store to data hub.\r
- //\r
- EfiStatus = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- WinNtIoProtocolNotifyFunction,\r
- ImageHandle,\r
- &Event\r
- );\r
- ASSERT (!EFI_ERROR (EfiStatus));\r
-\r
- EfiStatus = gBS->RegisterProtocolNotify (\r
- &gEfiWinNtIoProtocolGuid,\r
- Event,\r
- &Registration\r
- );\r
- ASSERT (!EFI_ERROR (EfiStatus));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINTN\r
-Atoi (\r
- CHAR16 *String\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Convert a unicode string to a UINTN\r
-\r
-Arguments:\r
- String - Unicode string.\r
-\r
-Returns:\r
- UINTN of the number represented by String.\r
-\r
---*/\r
-{\r
- UINTN Number;\r
- CHAR16 *Str;\r
-\r
- //\r
- // skip preceeding white space\r
- //\r
- Str = String;\r
- while ((*Str) && (*Str == ' ' || *Str == '"')) {\r
- Str++;\r
- }\r
- //\r
- // Convert ot a Number\r
- //\r
- Number = 0;\r
- while (*Str != '\0') {\r
- if ((*Str >= '0') && (*Str <= '9')) {\r
- Number = (Number * 10) +*Str - '0';\r
- } else {\r
- break;\r
- }\r
-\r
- Str++;\r
- }\r
-\r
- return Number;\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-WinNtIoProtocolNotifyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This function will log memory size data to data hub.\r
-\r
-Arguments:\r
-Event - Event whose notification function is being invoked.\r
-Context - Pointer to the notification function's context.\r
-\r
-Returns:\r
- EFI_STATUS.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData;\r
- EFI_DATA_RECORD_HEADER *Record;\r
- EFI_SUBCLASS_TYPE1_HEADER *DataHeader;\r
- UINTN HandleCount;\r
- UINTN HandleIndex;\r
- UINT64 MonotonicCount;\r
- BOOLEAN RecordFound;\r
- EFI_HANDLE *HandleBuffer;\r
- EFI_WIN_NT_IO_PROTOCOL *WinNtIo;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- UINT64 TotalMemorySize;\r
-\r
- DataHub = NULL;\r
- MonotonicCount = 0;\r
- RecordFound = FALSE;\r
-\r
- //\r
- // Retrieve the list of all handles from the handle database.\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- &gEfiWinNtIoProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- //\r
- // Locate DataHub protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- //\r
- // Search the Handle array to find the meory size information.\r
- //\r
- for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
- Status = gBS->OpenProtocol (\r
- HandleBuffer[HandleIndex],\r
- &gEfiWinNtIoProtocolGuid,\r
- &WinNtIo,\r
- Context,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&\r
- CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtMemoryGuid)\r
- ) {\r
- //\r
- // Check if this record has been stored in data hub.\r
- //\r
- do {\r
- Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);\r
- if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {\r
- DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);\r
- if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&\r
- (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)\r
- ) {\r
- RecordFound = TRUE;\r
- }\r
- }\r
- } while (MonotonicCount != 0);\r
-\r
- if (RecordFound) {\r
- RecordFound = FALSE;\r
- continue;\r
- }\r
- //\r
- // Initialize data record.\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
- TotalMemorySize = (UINT64) Atoi (WinNtIo->EnvString);\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
- //\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
- }\r
-\r
- gBS->CloseProtocol (\r
- HandleBuffer[HandleIndex],\r
- &gEfiWinNtIoProtocolGuid,\r
- Context,\r
- NULL\r
- );\r
- }\r
-}\r
-\r