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
[];
33 LogRecordDataToDataHub (
34 EFI_DATA_HUB_PROTOCOL
*DataHub
,
66 EFI_MISC_SUBCLASS_DRIVER_DATA MiscSubclass
;
70 // Do nothing if data parameters are not valid.
72 if (RecordLen
== 0 || RecordData
== NULL
) {
75 "RecordLen == %d RecordData == %xh\n",
80 return EFI_INVALID_PARAMETER
;
83 // Assemble Data Hub record.
85 MiscSubclass
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
86 MiscSubclass
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
87 MiscSubclass
.Header
.Instance
= 1;
88 MiscSubclass
.Header
.SubInstance
= 1;
89 MiscSubclass
.Header
.RecordType
= RecordType
;
98 // Log Data Hub record.
100 Status
= DataHub
->LogData (
102 &gEfiMiscSubClassGuid
,
103 &gEfiMiscSubClassGuid
,
104 EFI_DATA_RECORD_CLASS_DATA
,
106 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
109 if (EFI_ERROR (Status
)) {
112 "LogData(%d bytes) == %r\n",
113 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + RecordLen
,
124 MiscSubclassDriverEntryPoint (
125 IN EFI_HANDLE ImageHandle
,
126 IN EFI_SYSTEM_TABLE
*SystemTable
131 Standard EFI driver point. This driver parses the mMiscSubclassDataTable
132 structure and reports any generated data to the DataHub.
137 Handle for the image of this driver
140 Pointer to the EFI System Table
145 The data was successfully reported to the Data Hub.
149 EFI_MISC_SUBCLASS_DRIVER_DATA RecordData
;
150 EFI_DATA_HUB_PROTOCOL
*DataHub
;
151 EFI_HII_PROTOCOL
*Hii
;
152 EFI_HII_PACKAGES
*PackageList
;
153 EFI_HII_HANDLE HiiHandle
;
156 BOOLEAN LogRecordData
;
157 EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData
;
158 UINT64 TotalMemorySize
;
159 CHAR16
*Nt32MemString
;
163 // Initialize constant portion of subclass header.
165 RecordData
.Header
.Version
= EFI_MISC_SUBCLASS_VERSION
;
166 RecordData
.Header
.HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
167 RecordData
.Header
.Instance
= 1;
168 RecordData
.Header
.SubInstance
= 1;
171 // Locate data hub protocol.
173 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
175 if (EFI_ERROR (Status
)) {
176 DEBUG ((EFI_D_ERROR
, "Could not locate DataHub protocol. %r\n", Status
));
178 } else if (DataHub
== NULL
) {
179 DEBUG ((EFI_D_ERROR
, "LocateProtocol(DataHub) returned NULL pointer!\n"));
180 return EFI_DEVICE_ERROR
;
183 // Locate hii protocol.
185 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, &Hii
);
187 if (EFI_ERROR (Status
)) {
188 DEBUG ((EFI_D_ERROR
, "Could not locate Hii protocol. %r\n", Status
));
190 } else if (Hii
== NULL
) {
191 DEBUG ((EFI_D_ERROR
, "LocateProtocol(Hii) returned NULL pointer!\n"));
192 return EFI_DEVICE_ERROR
;
195 // Add our default strings to the HII database. They will be modified later.
197 PackageList
= PreparePackages (1, &gEfiMiscSubClassGuid
, MiscSubclassStrings
);
198 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
199 FreePool (PackageList
);
201 if (EFI_ERROR (Status
)) {
202 DEBUG ((EFI_D_ERROR
, "Could not log default strings to Hii. %r\n", Status
));
208 for (Index
= 0; Index
< mMiscSubclassDataTableEntries
; ++Index
) {
210 // Stupidity check! Do nothing if RecordLen is zero.
211 // %%TBD - Should this be an error or a mechanism for ignoring
212 // records in the Data Table?
214 if (mMiscSubclassDataTable
[Index
].RecordLen
== 0) {
217 "mMiscSubclassDataTable[%d].RecordLen == 0\n",
224 // Initialize per-record portion of subclass header and
225 // copy static data into data portion of subclass record.
227 RecordData
.Header
.RecordType
= mMiscSubclassDataTable
[Index
].RecordType
;
229 if (mMiscSubclassDataTable
[Index
].RecordData
== NULL
) {
232 mMiscSubclassDataTable
[Index
].RecordLen
237 mMiscSubclassDataTable
[Index
].RecordData
,
238 mMiscSubclassDataTable
[Index
].RecordLen
242 // If the entry does not have a function pointer, just log the data.
244 if (mMiscSubclassDataTable
[Index
].Function
== NULL
) {
246 // Log RecordData to Data Hub.
248 Status
= DataHub
->LogData (
250 &gEfiMiscSubClassGuid
,
251 &gEfiMiscSubClassGuid
,
252 EFI_DATA_RECORD_CLASS_DATA
,
254 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
257 if (EFI_ERROR (Status
)) {
260 "LogData(%d bytes) == %r\n",
261 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
269 // The entry has a valid function pointer.
270 // Keep calling the function and logging data until there
271 // is no more data to log.
274 Status
= (*mMiscSubclassDataTable
[Index
].Function
)(mMiscSubclassDataTable
[Index
].RecordType
, &mMiscSubclassDataTable
[Index
].RecordLen
, &RecordData
.Record
, &LogRecordData
);
275 if (EFI_ERROR (Status
)) {
279 if (!LogRecordData
) {
283 Status
= DataHub
->LogData (
285 &gEfiMiscSubClassGuid
,
286 &gEfiMiscSubClassGuid
,
287 EFI_DATA_RECORD_CLASS_DATA
,
289 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
292 if (EFI_ERROR (Status
)) {
295 "LogData(%d bytes) == %r\n",
296 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + mMiscSubclassDataTable
[Index
].RecordLen
,
305 // Log Memory Size info based on PCD setting.
307 MemorySubClassData
.Header
.Instance
= 1;
308 MemorySubClassData
.Header
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
309 MemorySubClassData
.Header
.RecordType
= EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
;
312 // Process Memory String in form size!size ...
313 // So 64!64 is 128 MB
315 Nt32MemString
= PcdGetPtr (PcdWinNtMemorySize
);
316 for (TotalMemorySize
= 0; *Nt32MemString
!= '\0';) {
317 TotalMemorySize
+= StrDecimalToUint64 (Nt32MemString
);
318 while (*Nt32MemString
!= '\0') {
319 if (*Nt32MemString
== '!') {
327 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayStartAddress
= 0;
328 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayEndAddress
= LShiftU64 (TotalMemorySize
, 20) - 1;
329 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.ProducerName
= gEfiMemoryProducerGuid
;
330 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.Instance
= 1;
331 MemorySubClassData
.Record
.ArrayStartAddress
.PhysicalMemoryArrayLink
.SubInstance
= EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
;
332 MemorySubClassData
.Record
.ArrayStartAddress
.MemoryArrayPartitionWidth
= 0;
335 // Store memory size data record to data hub.
337 Status
= DataHub
->LogData (
339 &gEfiMemorySubClassGuid
,
340 &gEfiMemoryProducerGuid
,
341 EFI_DATA_RECORD_CLASS_DATA
,
343 sizeof (EFI_SUBCLASS_TYPE1_HEADER
) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
)