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.
23 #include "MiscSubclassDriver.h"
26 extern UINT8 MiscSubclassStrings
[];
30 WinNtIoProtocolNotifyFunction (
39 LogRecordDataToDataHub (
40 EFI_DATA_HUB_PROTOCOL
*DataHub
,
72 EFI_MISC_SUBCLASS_DRIVER_DATA MiscSubclass
;
76 // Do nothing if data parameters are not valid.
78 if (RecordLen
== 0 || RecordData
== NULL
) {
81 "RecordLen == %d RecordData == %xh\n",
86 return EFI_INVALID_PARAMETER
;
89 // Assemble Data Hub record.
91 MiscSubclass
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
92 MiscSubclass
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
93 MiscSubclass
.Header
.Instance
= 1;
94 MiscSubclass
.Header
.SubInstance
= 1;
95 MiscSubclass
.Header
.RecordType
= RecordType
;
104 // Log Data Hub record.
106 EfiStatus
= DataHub
->LogData (
108 &gEfiMiscSubClassGuid
,
109 &gEfiMiscSubClassGuid
,
110 EFI_DATA_RECORD_CLASS_DATA
,
112 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
115 if (EFI_ERROR (EfiStatus
)) {
118 "LogData(%d bytes) == %r\n",
119 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
,
130 MiscSubclassDriverEntryPoint (
131 IN EFI_HANDLE ImageHandle
,
132 IN EFI_SYSTEM_TABLE
*SystemTable
137 Standard EFI driver point. This driver parses the mMiscSubclassDataTable
138 structure and reports any generated data to the DataHub.
143 Handle for the image of this driver
146 Pointer to the EFI System Table
151 The data was successfully reported to the Data Hub.
155 EFI_MISC_SUBCLASS_DRIVER_DATA RecordData
;
156 EFI_DATA_HUB_PROTOCOL
*DataHub
;
157 EFI_HII_PROTOCOL
*Hii
;
158 EFI_HII_PACKAGES
*PackageList
;
159 EFI_HII_HANDLE HiiHandle
;
160 EFI_STATUS EfiStatus
;
162 BOOLEAN LogRecordData
;
168 // Initialize constant portion of subclass header.
170 RecordData
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
171 RecordData
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
172 RecordData
.Header
.Instance
= 1;
173 RecordData
.Header
.SubInstance
= 1;
176 // Locate data hub protocol.
178 EfiStatus
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
180 if (EFI_ERROR (EfiStatus
)) {
181 DEBUG ((EFI_D_ERROR
, "Could not locate DataHub protocol. %r\n", EfiStatus
));
183 } else if (DataHub
== NULL
) {
184 DEBUG ((EFI_D_ERROR
, "LocateProtocol(DataHub) returned NULL pointer!\n"));
185 return EFI_DEVICE_ERROR
;
188 // Locate hii protocol.
190 EfiStatus
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, &Hii
);
192 if (EFI_ERROR (EfiStatus
)) {
193 DEBUG ((EFI_D_ERROR
, "Could not locate Hii protocol. %r\n", EfiStatus
));
195 } else if (Hii
== NULL
) {
196 DEBUG ((EFI_D_ERROR
, "LocateProtocol(Hii) returned NULL pointer!\n"));
197 return EFI_DEVICE_ERROR
;
200 // Add our default strings to the HII database. They will be modified later.
202 PackageList
= PreparePackages (1, &gEfiMiscSubClassGuid
, MiscSubclassStrings
);
203 EfiStatus
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
204 FreePool (PackageList
);
206 if (EFI_ERROR (EfiStatus
)) {
207 DEBUG ((EFI_D_ERROR
, "Could not log default strings to Hii. %r\n", EfiStatus
));
213 for (Index
= 0; Index
< mMiscSubclassDataTableEntries
; ++Index
) {
215 // Stupidity check! Do nothing if RecordLen is zero.
216 // %%TBD - Should this be an error or a mechanism for ignoring
217 // records in the Data Table?
219 if (mMiscSubclassDataTable
[Index
].RecordLen
== 0) {
222 "mMiscSubclassDataTable[%d].RecordLen == 0\n",
229 // Initialize per-record portion of subclass header and
230 // copy static data into data portion of subclass record.
232 RecordData
.Header
.RecordType
= mMiscSubclassDataTable
[Index
].RecordType
;
234 if (mMiscSubclassDataTable
[Index
].RecordData
== NULL
) {
237 mMiscSubclassDataTable
[Index
].RecordLen
242 mMiscSubclassDataTable
[Index
].RecordData
,
243 mMiscSubclassDataTable
[Index
].RecordLen
247 // If the entry does not have a function pointer, just log the data.
249 if (mMiscSubclassDataTable
[Index
].Function
== NULL
) {
251 // Log RecordData to Data Hub.
253 EfiStatus
= DataHub
->LogData (
255 &gEfiMiscSubClassGuid
,
256 &gEfiMiscSubClassGuid
,
257 EFI_DATA_RECORD_CLASS_DATA
,
259 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
262 if (EFI_ERROR (EfiStatus
)) {
265 "LogData(%d bytes) == %r\n",
266 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
274 // The entry has a valid function pointer.
275 // Keep calling the function and logging data until there
276 // is no more data to log.
282 EfiStatus
= (*mMiscSubclassDataTable
[Index
].Function
)
284 mMiscSubclassDataTable
[Index
].RecordType
, &mMiscSubclassDataTable
[Index
].RecordLen
, &RecordData
.Record
, &
291 if (EFI_ERROR (EfiStatus
)) {
295 if (!LogRecordData
) {
301 EfiStatus
= DataHub
->LogData (
303 &gEfiMiscSubClassGuid
,
304 &gEfiMiscSubClassGuid
,
305 EFI_DATA_RECORD_CLASS_DATA
,
307 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
310 if (EFI_ERROR (EfiStatus
)) {
313 "LogData(%d bytes) == %r\n",
314 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
321 // Install notify function to fetch memory data through WinNtIo protocol and store to data hub.
323 EfiStatus
= gBS
->CreateEvent (
326 WinNtIoProtocolNotifyFunction
,
330 ASSERT (!EFI_ERROR (EfiStatus
));
332 EfiStatus
= gBS
->RegisterProtocolNotify (
333 &gEfiWinNtIoProtocolGuid
,
337 ASSERT (!EFI_ERROR (EfiStatus
));
349 Convert a unicode string to a UINTN
352 String - Unicode string.
355 UINTN of the number represented by String.
363 // skip preceeding white space
366 while ((*Str
) && (*Str
== ' ' || *Str
== '"')) {
370 // Convert ot a Number
373 while (*Str
!= '\0') {
374 if ((*Str
>= '0') && (*Str
<= '9')) {
375 Number
= (Number
* 10) +*Str
- '0';
388 WinNtIoProtocolNotifyFunction (
395 This function will log memory size data to data hub.
398 Event - Event whose notification function is being invoked.
399 Context - Pointer to the notification function's context.
407 EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData
;
408 EFI_DATA_RECORD_HEADER
*Record
;
409 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
412 UINT64 MonotonicCount
;
414 EFI_HANDLE
*HandleBuffer
;
415 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
416 EFI_DATA_HUB_PROTOCOL
*DataHub
;
417 UINT64 TotalMemorySize
;
424 // Retrieve the list of all handles from the handle database.
426 Status
= gBS
->LocateHandleBuffer (
428 &gEfiWinNtIoProtocolGuid
,
433 if (EFI_ERROR (Status
)) {
437 // Locate DataHub protocol.
439 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
440 if (EFI_ERROR (Status
)) {
444 // Search the Handle array to find the meory size information.
446 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
447 Status
= gBS
->OpenProtocol (
448 HandleBuffer
[HandleIndex
],
449 &gEfiWinNtIoProtocolGuid
,
453 EFI_OPEN_PROTOCOL_GET_PROTOCOL
455 if (EFI_ERROR (Status
)) {
459 if ((WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) &&
460 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtMemoryGuid
)
463 // Check if this record has been stored in data hub.
466 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
467 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
468 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
469 if (CompareGuid (&Record
->DataRecordGuid
, &gEfiProcessorSubClassGuid
) &&
470 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
475 } while (MonotonicCount
!= 0);
482 // Initialize data record.
484 MemorySubClassData
.Header
.Instance
= 1;
485 MemorySubClassData
.Header
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
486 MemorySubClassData
.Header
.RecordType
= EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
;
488 TotalMemorySize
= (UINT64
) Atoi (WinNtIo
->EnvString
);
490 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayStartAddress
= 0;
491 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayEndAddress
= LShiftU64 (TotalMemorySize
, 20) - 1;
492 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.ProducerName
= gEfiMemoryProducerGuid
;
493 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.Instance
= 1;
494 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
495 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayPartitionWidth
= 0;
498 // Store memory size data record to data hub.
500 Status
= DataHub
->LogData (
502 &gEfiMemorySubClassGuid
,
503 &gEfiMemoryProducerGuid
,
504 EFI_DATA_RECORD_CLASS_DATA
,
506 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
)
511 HandleBuffer
[HandleIndex
],
512 &gEfiWinNtIoProtocolGuid
,