3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 MiscSubclassDriverEntryPoint.c
18 This driver parses the mMiscSubclassDataTable structure and reports
19 any generated data to the DataHub.
24 // Include common header file for this module.
26 #include "CommonHeader.h"
28 #include "MiscSubclassDriver.h"
31 extern UINT8 MiscSubclassStrings
[];
35 WinNtIoProtocolNotifyFunction (
44 LogRecordDataToDataHub (
45 EFI_DATA_HUB_PROTOCOL
*DataHub
,
77 EFI_MISC_SUBCLASS_DRIVER_DATA MiscSubclass
;
81 // Do nothing if data parameters are not valid.
83 if (RecordLen
== 0 || RecordData
== NULL
) {
86 "RecordLen == %d RecordData == %xh\n",
91 return EFI_INVALID_PARAMETER
;
94 // Assemble Data Hub record.
96 MiscSubclass
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
97 MiscSubclass
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
98 MiscSubclass
.Header
.Instance
= 1;
99 MiscSubclass
.Header
.SubInstance
= 1;
100 MiscSubclass
.Header
.RecordType
= RecordType
;
103 &MiscSubclass
.Record
,
109 // Log Data Hub record.
111 EfiStatus
= DataHub
->LogData (
113 &gEfiMiscSubClassGuid
,
114 &gEfiMiscSubClassGuid
,
115 EFI_DATA_RECORD_CLASS_DATA
,
117 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
120 if (EFI_ERROR (EfiStatus
)) {
123 "LogData(%d bytes) == %r\n",
124 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
,
135 MiscSubclassDriverEntryPoint (
136 IN EFI_HANDLE ImageHandle
,
137 IN EFI_SYSTEM_TABLE
*SystemTable
142 Standard EFI driver point. This driver parses the mMiscSubclassDataTable
143 structure and reports any generated data to the DataHub.
148 Handle for the image of this driver
151 Pointer to the EFI System Table
156 The data was successfully reported to the Data Hub.
160 EFI_MISC_SUBCLASS_DRIVER_DATA RecordData
;
161 EFI_DATA_HUB_PROTOCOL
*DataHub
;
162 EFI_HII_PROTOCOL
*Hii
;
163 EFI_HII_PACKAGES
*PackageList
;
164 EFI_HII_HANDLE HiiHandle
;
165 EFI_STATUS EfiStatus
;
167 BOOLEAN LogRecordData
;
173 // Initialize constant portion of subclass header.
175 RecordData
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
176 RecordData
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
177 RecordData
.Header
.Instance
= 1;
178 RecordData
.Header
.SubInstance
= 1;
181 // Locate data hub protocol.
183 EfiStatus
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
185 if (EFI_ERROR (EfiStatus
)) {
186 DEBUG ((EFI_D_ERROR
, "Could not locate DataHub protocol. %r\n", EfiStatus
));
188 } else if (DataHub
== NULL
) {
189 DEBUG ((EFI_D_ERROR
, "LocateProtocol(DataHub) returned NULL pointer!\n"));
190 return EFI_DEVICE_ERROR
;
193 // Locate hii protocol.
195 EfiStatus
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, &Hii
);
197 if (EFI_ERROR (EfiStatus
)) {
198 DEBUG ((EFI_D_ERROR
, "Could not locate Hii protocol. %r\n", EfiStatus
));
200 } else if (Hii
== NULL
) {
201 DEBUG ((EFI_D_ERROR
, "LocateProtocol(Hii) returned NULL pointer!\n"));
202 return EFI_DEVICE_ERROR
;
205 // Add our default strings to the HII database. They will be modified later.
207 PackageList
= PreparePackages (1, &gEfiMiscSubClassGuid
, MiscSubclassStrings
);
208 EfiStatus
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
209 FreePool (PackageList
);
211 if (EFI_ERROR (EfiStatus
)) {
212 DEBUG ((EFI_D_ERROR
, "Could not log default strings to Hii. %r\n", EfiStatus
));
218 for (Index
= 0; Index
< mMiscSubclassDataTableEntries
; ++Index
) {
220 // Stupidity check! Do nothing if RecordLen is zero.
221 // %%TBD - Should this be an error or a mechanism for ignoring
222 // records in the Data Table?
224 if (mMiscSubclassDataTable
[Index
].RecordLen
== 0) {
227 "mMiscSubclassDataTable[%d].RecordLen == 0\n",
234 // Initialize per-record portion of subclass header and
235 // copy static data into data portion of subclass record.
237 RecordData
.Header
.RecordType
= mMiscSubclassDataTable
[Index
].RecordType
;
239 if (mMiscSubclassDataTable
[Index
].RecordData
== NULL
) {
242 mMiscSubclassDataTable
[Index
].RecordLen
247 mMiscSubclassDataTable
[Index
].RecordData
,
248 mMiscSubclassDataTable
[Index
].RecordLen
252 // If the entry does not have a function pointer, just log the data.
254 if (mMiscSubclassDataTable
[Index
].Function
== NULL
) {
256 // Log RecordData to Data Hub.
258 EfiStatus
= DataHub
->LogData (
260 &gEfiMiscSubClassGuid
,
261 &gEfiMiscSubClassGuid
,
262 EFI_DATA_RECORD_CLASS_DATA
,
264 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
267 if (EFI_ERROR (EfiStatus
)) {
270 "LogData(%d bytes) == %r\n",
271 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
279 // The entry has a valid function pointer.
280 // Keep calling the function and logging data until there
281 // is no more data to log.
287 EfiStatus
= (*mMiscSubclassDataTable
[Index
].Function
)
289 mMiscSubclassDataTable
[Index
].RecordType
, &mMiscSubclassDataTable
[Index
].RecordLen
, &RecordData
.Record
, &
296 if (EFI_ERROR (EfiStatus
)) {
300 if (!LogRecordData
) {
306 EfiStatus
= DataHub
->LogData (
308 &gEfiMiscSubClassGuid
,
309 &gEfiMiscSubClassGuid
,
310 EFI_DATA_RECORD_CLASS_DATA
,
312 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
315 if (EFI_ERROR (EfiStatus
)) {
318 "LogData(%d bytes) == %r\n",
319 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
326 // Install notify function to fetch memory data through WinNtIo protocol and store to data hub.
328 EfiStatus
= gBS
->CreateEvent (
331 WinNtIoProtocolNotifyFunction
,
335 ASSERT (!EFI_ERROR (EfiStatus
));
337 EfiStatus
= gBS
->RegisterProtocolNotify (
338 &gEfiWinNtIoProtocolGuid
,
342 ASSERT (!EFI_ERROR (EfiStatus
));
354 Convert a unicode string to a UINTN
357 String - Unicode string.
360 UINTN of the number represented by String.
368 // skip preceeding white space
371 while ((*Str
) && (*Str
== ' ' || *Str
== '"')) {
375 // Convert ot a Number
378 while (*Str
!= '\0') {
379 if ((*Str
>= '0') && (*Str
<= '9')) {
380 Number
= (Number
* 10) +*Str
- '0';
393 WinNtIoProtocolNotifyFunction (
400 This function will log memory size data to data hub.
403 Event - Event whose notification function is being invoked.
404 Context - Pointer to the notification function's context.
412 EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData
;
413 EFI_DATA_RECORD_HEADER
*Record
;
414 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
417 UINT64 MonotonicCount
;
419 EFI_HANDLE
*HandleBuffer
;
420 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
421 EFI_DATA_HUB_PROTOCOL
*DataHub
;
422 UINT64 TotalMemorySize
;
429 // Retrieve the list of all handles from the handle database.
431 Status
= gBS
->LocateHandleBuffer (
433 &gEfiWinNtIoProtocolGuid
,
438 if (EFI_ERROR (Status
)) {
442 // Locate DataHub protocol.
444 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
445 if (EFI_ERROR (Status
)) {
449 // Search the Handle array to find the meory size information.
451 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
452 Status
= gBS
->OpenProtocol (
453 HandleBuffer
[HandleIndex
],
454 &gEfiWinNtIoProtocolGuid
,
458 EFI_OPEN_PROTOCOL_GET_PROTOCOL
460 if (EFI_ERROR (Status
)) {
464 if ((WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) &&
465 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtMemoryGuid
)
468 // Check if this record has been stored in data hub.
471 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
472 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
473 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
474 if (CompareGuid (&Record
->DataRecordGuid
, &gEfiProcessorSubClassGuid
) &&
475 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
480 } while (MonotonicCount
!= 0);
487 // Initialize data record.
489 MemorySubClassData
.Header
.Instance
= 1;
490 MemorySubClassData
.Header
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
491 MemorySubClassData
.Header
.RecordType
= EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
;
493 TotalMemorySize
= (UINT64
) Atoi (WinNtIo
->EnvString
);
495 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayStartAddress
= 0;
496 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayEndAddress
= LShiftU64 (TotalMemorySize
, 20) - 1;
497 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.ProducerName
= gEfiMemoryProducerGuid
;
498 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.Instance
= 1;
499 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
500 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayPartitionWidth
= 0;
503 // Store memory size data record to data hub.
505 Status
= DataHub
->LogData (
507 &gEfiMemorySubClassGuid
,
508 &gEfiMemoryProducerGuid
,
509 EFI_DATA_RECORD_CLASS_DATA
,
511 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
)
516 HandleBuffer
[HandleIndex
],
517 &gEfiWinNtIoProtocolGuid
,