]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Universal / DataHub / DataHub / Dxe / DataHub.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 DataHub.c\r
15\r
16Abstract:\r
17\r
18 This code produces the Data Hub protocol. It preloads the data hub\r
19 with status information copied in from PEI HOBs.\r
20 \r
21 Only code that implements the Data Hub protocol should go in this file!\r
22\r
23 The Term MTC stands for MonoTonicCounter. \r
24\r
25 For more information please look at DataHub.doc\r
26\r
27 NOTE: For extra security of the log GetNextDataRecord () could return a copy\r
28 of the data record.\r
29--*/\r
30\r
31#include "DataHub.h"\r
32\r
33CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };\r
34\r
35//\r
36// Worker functions private to this file\r
37//\r
38STATIC\r
39DATA_HUB_FILTER_DRIVER *\r
40FindFilterDriverByEvent (\r
41 IN LIST_ENTRY *Head,\r
42 IN EFI_EVENT Event\r
43 );\r
44\r
45STATIC\r
46EFI_DATA_RECORD_HEADER *\r
47GetNextDataRecord (\r
48 IN LIST_ENTRY *Head,\r
49 IN UINT64 ClassFilter,\r
50 IN OUT UINT64 *PtrCurrentMTC\r
51 );\r
52\r
1cc8ee78 53STATIC\r
878ddf1f 54EFI_STATUS\r
55EFIAPI\r
56DataHubLogData (\r
57 IN EFI_DATA_HUB_PROTOCOL *This,\r
58 IN EFI_GUID *DataRecordGuid,\r
59 IN EFI_GUID *ProducerName,\r
60 IN UINT64 DataRecordClass,\r
61 IN VOID *RawData,\r
62 IN UINT32 RawDataSize\r
63 )\r
64/*++\r
65\r
66Routine Description:\r
67\r
68 Log data record into the data logging hub\r
69\r
70Arguments:\r
71\r
72 This - Protocol instance structure\r
73\r
74 DataRecordGuid - GUID that defines record contents\r
75\r
76 ProducerName - GUID that defines the name of the producer of the data\r
77\r
78 DataRecordClass - Class that defines generic record type\r
79\r
80 RawData - Data Log record as defined by DataRecordGuid\r
81 \r
82 RawDataSize - Size of Data Log data in bytes\r
83\r
84Returns: \r
85\r
86 EFI_SUCCESS - If data was logged\r
87\r
88 EFI_OUT_OF_RESOURCES - If data was not logged due to lack of system \r
89 resources.\r
90--*/\r
91{\r
92 EFI_STATUS Status;\r
93 DATA_HUB_INSTANCE *Private;\r
94 EFI_DATA_ENTRY *LogEntry;\r
95 UINT32 TotalSize;\r
96 UINT32 RecordSize;\r
97 EFI_DATA_RECORD_HEADER *Record;\r
98 VOID *Raw;\r
99 DATA_HUB_FILTER_DRIVER *FilterEntry;\r
100 LIST_ENTRY *Link;\r
101 LIST_ENTRY *Head;\r
102\r
103 Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
104\r
105 //\r
106 // Combine the storage for the internal structs and a copy of the log record.\r
107 // Record follows PrivateLogEntry. The consumer will be returned a pointer\r
108 // to Record so we don't what it to be the thing that was allocated from\r
109 // pool, so the consumer can't free an data record by mistake.\r
110 //\r
111 RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;\r
112 TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize;\r
113\r
114 //\r
115 // The Logging action is the critical section, so it is locked.\r
116 // The MTC asignment & update, time, and logging must be an\r
117 // atomic operation, so use the lock.\r
118 //\r
119 Status = EfiAcquireLockOrFail (&Private->DataLock);\r
120 if (EFI_ERROR (Status)) {\r
121 //\r
122 // Reentrancy detected so exit!\r
123 //\r
124 return Status;\r
125 }\r
126\r
127 Status = gBS->AllocatePool (EfiBootServicesData, TotalSize, (VOID **) &LogEntry);\r
128 if (EFI_ERROR (Status)) {\r
129 EfiReleaseLock (&Private->DataLock);\r
130 return EFI_OUT_OF_RESOURCES;\r
131 }\r
132\r
133 ZeroMem (LogEntry, TotalSize);\r
134\r
135 Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);\r
136 Raw = (VOID *) (Record + 1);\r
137\r
138 //\r
139 // Build Standard Log Header\r
140 //\r
141 Record->Version = EFI_DATA_RECORD_HEADER_VERSION;\r
142 Record->HeaderSize = sizeof (EFI_DATA_RECORD_HEADER);\r
143 Record->RecordSize = RecordSize;\r
144 CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));\r
145 CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));\r
146 Record->DataRecordClass = DataRecordClass;\r
147\r
148 Record->LogMonotonicCount = Private->GlobalMonotonicCount++;\r
149\r
150 gRT->GetTime (&Record->LogTime, NULL);\r
151\r
152 //\r
153 // Insert log into the internal linked list.\r
154 //\r
155 LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE;\r
156 LogEntry->Record = Record;\r
157 LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize;\r
158 InsertTailList (&Private->DataListHead, &LogEntry->Link);\r
159\r
160 CopyMem (Raw, RawData, RawDataSize);\r
161\r
162 EfiReleaseLock (&Private->DataLock);\r
163\r
164 //\r
165 // Send Signal to all the filter drivers which are interested\r
166 // in the record's class and guid.\r
167 //\r
168 Head = &Private->FilterDriverListHead;\r
169 for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
170 FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
171 if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&\r
172 (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || \r
173 CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {\r
174 gBS->SignalEvent (FilterEntry->Event);\r
175 }\r
176 }\r
177\r
178 return EFI_SUCCESS;\r
179}\r
180\r
1cc8ee78 181STATIC\r
878ddf1f 182EFI_STATUS\r
183EFIAPI\r
184DataHubGetNextRecord (\r
185 IN EFI_DATA_HUB_PROTOCOL *This,\r
186 IN OUT UINT64 *MonotonicCount,\r
187 IN EFI_EVENT *FilterDriverEvent, OPTIONAL\r
188 OUT EFI_DATA_RECORD_HEADER **Record\r
189 )\r
190/*++\r
191\r
192Routine Description:\r
193\r
194 Get a previously logged data record and the MonotonicCount for the next\r
195 availible Record. This allows all records or all records later \r
196 than a give MonotonicCount to be returned. If an optional FilterDriverEvent\r
197 is passed in with a MonotonicCout of zero return the first record \r
198 not yet read by the filter driver. If FilterDriverEvent is NULL and \r
199 MonotonicCount is zero return the first data record.\r
200\r
201Arguments:\r
202\r
203 This - The EFI_DATA_HUB_PROTOCOL instance.\r
204 MonotonicCount - Specifies the Record to return. On input, zero means\r
205 return the first record. On output, contains the next\r
206 record to availible. Zero indicates no more records.\r
207 FilterDriverEvent - If FilterDriverEvent is not passed in a MonotonicCount \r
208 of zero, it means to return the first data record. \r
209 If FilterDriverEvent is passed in, then a MonotonicCount \r
210 of zero means to return the first data not yet read by \r
211 FilterDriverEvent.\r
212 Record - Returns a dynamically allocated memory buffer with a data \r
213 record that matches MonotonicCount.\r
214\r
215Returns: \r
216\r
217 EFI_SUCCESS - Data was returned in Record.\r
218 EFI_INVALID_PARAMETER - FilterDriverEvent was passed in but does not exist.\r
219 EFI_NOT_FOUND - MonotonicCount does not match any data record in the\r
220 system. If a MonotonicCount of zero was passed in, then\r
221 no data records exist in the system.\r
222 EFI_OUT_OF_RESOURCES - Record was not returned due to lack of system resources.\r
223\r
224--*/\r
225{\r
226 DATA_HUB_INSTANCE *Private;\r
227 DATA_HUB_FILTER_DRIVER *FilterDriver;\r
228 UINT64 ClassFilter;\r
229 UINT64 FilterMonotonicCount;\r
230\r
231 Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
232\r
233 FilterDriver = NULL;\r
234 FilterMonotonicCount = 0;\r
235 ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
236 EFI_DATA_RECORD_CLASS_ERROR |\r
237 EFI_DATA_RECORD_CLASS_DATA |\r
238 EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
239\r
240 if (FilterDriverEvent != NULL) {\r
241 //\r
242 // For events the beginning is the last unread record. This info is\r
243 // stored in the instance structure, so we must look up the event\r
244 // to get the data.\r
245 //\r
246 FilterDriver = FindFilterDriverByEvent (\r
247 &Private->FilterDriverListHead,\r
248 *FilterDriverEvent\r
249 );\r
250 if (FilterDriver == NULL) {\r
251 return EFI_INVALID_PARAMETER;\r
252 }\r
253 //\r
254 // Use the Class filter the event was created with.\r
255 //\r
256 ClassFilter = FilterDriver->ClassFilter;\r
257\r
258 if (*MonotonicCount == 0) {\r
259 //\r
260 // Use the MTC from the Filter Driver.\r
261 //\r
262 FilterMonotonicCount = FilterDriver->GetNextMonotonicCount;\r
263 if (FilterMonotonicCount != 0) {\r
264 //\r
265 // The GetNextMonotonicCount field remembers the last value from the previous time.\r
266 // But we already processed this vaule, so we need to find the next one. So if\r
267 // It is not the first time get the new record entry.\r
268 //\r
269 *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount);\r
270 *MonotonicCount = FilterMonotonicCount;\r
271 if (FilterMonotonicCount == 0) {\r
272 //\r
273 // If there is no new record to get exit now.\r
274 //\r
275 return EFI_NOT_FOUND;\r
276 }\r
277 }\r
278 }\r
279 }\r
280 //\r
281 // Return the record\r
282 //\r
283 *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);\r
284 if (*Record == NULL) {\r
285 return EFI_NOT_FOUND;\r
286 }\r
287\r
288 if (FilterDriver != NULL) {\r
289 //\r
290 // If we have a filter driver update the records that have been read.\r
291 // If MonotonicCount is zero No more reacords left.\r
292 //\r
293 if (*MonotonicCount == 0) {\r
294 if (FilterMonotonicCount != 0) {\r
295 //\r
296 // Return the result of our extra GetNextDataRecord.\r
297 //\r
298 FilterDriver->GetNextMonotonicCount = FilterMonotonicCount;\r
299 }\r
300 } else {\r
301 //\r
302 // Point to next undread record\r
303 //\r
304 FilterDriver->GetNextMonotonicCount = *MonotonicCount;\r
305 }\r
306 }\r
307\r
308 return EFI_SUCCESS;\r
309}\r
310\r
1cc8ee78 311STATIC\r
878ddf1f 312EFI_STATUS\r
313EFIAPI\r
314DataHubRegisterFilterDriver (\r
315 IN EFI_DATA_HUB_PROTOCOL * This,\r
316 IN EFI_EVENT FilterEvent,\r
317 IN EFI_TPL FilterTpl,\r
318 IN UINT64 FilterClass,\r
319 IN EFI_GUID * FilterDataRecordGuid OPTIONAL\r
320 )\r
321/*++\r
322\r
323Routine Description:\r
324\r
325 This function registers the data hub filter driver that is represented \r
326 by FilterEvent. Only one instance of each FilterEvent can be registered.\r
327 After the FilterEvent is registered, it will be signaled so it can sync \r
328 with data records that have been recorded prior to the FilterEvent being \r
329 registered.\r
330 \r
331Arguments:\r
332\r
333 This - The EFI_DATA_HUB_PROTOCOL instance.\r
334 FilterEvent - The EFI_EVENT to signal whenever data that matches \r
335 FilterClass is logged in the system.\r
336 FilterTpl - The maximum EFI_TPL at which FilterEvent can be \r
337 signaled. It is strongly recommended that you use the \r
338 lowest EFI_TPL possible.\r
339 FilterClass - FilterEvent will be signaled whenever a bit in \r
340 EFI_DATA_RECORD_HEADER.DataRecordClass is also set in \r
341 FilterClass. If FilterClass is zero, no class-based \r
342 filtering will be performed.\r
343 FilterDataRecordGuid - FilterEvent will be signaled whenever FilterDataRecordGuid \r
344 matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If \r
345 FilterDataRecordGuid is NULL, then no GUID-based filtering \r
346 will be performed. \r
347Returns: \r
348\r
349 EFI_SUCCESS - The filter driver event was registered.\r
350 EFI_ALREADY_STARTED - FilterEvent was previously registered and cannot be \r
351 registered again.\r
352 EFI_OUT_OF_RESOURCES - The filter driver event was not registered due to lack of \r
353 system resources.\r
354\r
355--*/\r
356{\r
357 DATA_HUB_INSTANCE *Private;\r
358 DATA_HUB_FILTER_DRIVER *FilterDriver;\r
359\r
360 Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
361\r
362 FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));\r
363 if (FilterDriver == NULL) {\r
364 return EFI_OUT_OF_RESOURCES;\r
365 }\r
366 //\r
367 // Initialize filter driver info\r
368 //\r
369 FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;\r
370 FilterDriver->Event = FilterEvent;\r
371 FilterDriver->Tpl = FilterTpl;\r
372 FilterDriver->GetNextMonotonicCount = 0;\r
373 if (FilterClass == 0) {\r
374 FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |\r
375 EFI_DATA_RECORD_CLASS_ERROR |\r
376 EFI_DATA_RECORD_CLASS_DATA |\r
377 EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
378 } else {\r
379 FilterDriver->ClassFilter = FilterClass;\r
380 }\r
381\r
382 if (FilterDataRecordGuid != NULL) {\r
383 CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));\r
384 }\r
385 //\r
386 // Search for duplicate entries\r
387 //\r
388 if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {\r
389 gBS->FreePool (FilterDriver);\r
390 return EFI_ALREADY_STARTED;\r
391 }\r
392 //\r
393 // Make insertion an atomic operation with the lock.\r
394 //\r
395 EfiAcquireLock (&Private->DataLock);\r
396 InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);\r
397 EfiReleaseLock (&Private->DataLock);\r
398\r
399 //\r
400 // Signal the Filter driver we just loaded so they will recieve all the\r
401 // previous history. If we did not signal here we would have to wait until\r
402 // the next data was logged to get the history. In a case where no next\r
403 // data was logged we would never get synced up.\r
404 //\r
405 gBS->SignalEvent (FilterEvent);\r
406\r
407 return EFI_SUCCESS;\r
408}\r
409\r
1cc8ee78 410STATIC\r
878ddf1f 411EFI_STATUS\r
412EFIAPI\r
413DataHubUnregisterFilterDriver (\r
414 IN EFI_DATA_HUB_PROTOCOL *This,\r
415 IN EFI_EVENT FilterEvent\r
416 )\r
417/*++\r
418\r
419Routine Description:\r
420\r
421 Remove a Filter Driver, so it no longer gets called when data \r
422 information is logged.\r
423\r
424Arguments:\r
425\r
426 This - Protocol instance structure\r
427\r
428 FilterEvent - Event that represents a filter driver that is to be \r
429 Unregistered.\r
430\r
431Returns: \r
432\r
433 EFI_SUCCESS - If FilterEvent was unregistered\r
434\r
435 EFI_NOT_FOUND - If FilterEvent does not exist\r
436\r
437--*/\r
438{\r
439 DATA_HUB_INSTANCE *Private;\r
440 DATA_HUB_FILTER_DRIVER *FilterDriver;\r
441\r
442 Private = DATA_HUB_INSTANCE_FROM_THIS (This);\r
443\r
444 //\r
445 // Search for duplicate entries\r
446 //\r
447 FilterDriver = FindFilterDriverByEvent (\r
448 &Private->FilterDriverListHead,\r
449 FilterEvent\r
450 );\r
451 if (FilterDriver == NULL) {\r
452 return EFI_NOT_FOUND;\r
453 }\r
454 //\r
455 // Make removal an atomic operation with the lock\r
456 //\r
457 EfiAcquireLock (&Private->DataLock);\r
458 RemoveEntryList (&FilterDriver->Link);\r
459 EfiReleaseLock (&Private->DataLock);\r
460\r
461 return EFI_SUCCESS;\r
462}\r
463//\r
464// STATIC Worker fucntions follow\r
465//\r
466STATIC\r
467DATA_HUB_FILTER_DRIVER *\r
468FindFilterDriverByEvent (\r
469 IN LIST_ENTRY *Head,\r
470 IN EFI_EVENT Event\r
471 )\r
472/*++\r
473\r
474Routine Description:\r
475 Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that\r
476 represents Event and return it.\r
477\r
478Arguments:\r
479\r
480 Head - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER\r
481 structures.\r
482\r
483 Event - Event to be search for in the Head list.\r
484\r
485Returns: \r
486\r
487 EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the\r
488 Head doubly linked list.\r
489\r
490 NULL - If Event is not in the list\r
491\r
492--*/\r
493{\r
494 DATA_HUB_FILTER_DRIVER *FilterEntry;\r
495 LIST_ENTRY *Link;\r
496\r
497 for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
498 FilterEntry = FILTER_ENTRY_FROM_LINK (Link);\r
499 if (FilterEntry->Event == Event) {\r
500 return FilterEntry;\r
501 }\r
502 }\r
503\r
504 return NULL;\r
505}\r
506\r
507STATIC\r
508EFI_DATA_RECORD_HEADER *\r
509GetNextDataRecord (\r
510 IN LIST_ENTRY *Head,\r
511 IN UINT64 ClassFilter,\r
512 IN OUT UINT64 *PtrCurrentMTC\r
513 )\r
514/*++\r
515\r
516Routine Description:\r
517 Search the Head doubly linked list for the passed in MTC. Return the \r
518 matching element in Head and the MTC on the next entry.\r
519\r
520Arguments:\r
521\r
522 Head - Head of Data Log linked list.\r
523\r
524 ClassFilter - Only match the MTC if it is in the same Class as the\r
525 ClassFilter.\r
526\r
527 PtrCurrentMTC - On IN contians MTC to search for. On OUT contians next\r
528 MTC in the data log list or zero if at end of the list.\r
529 \r
530Returns:\r
531\r
532 EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.\r
533\r
534 NULL - If no data record exists.\r
535\r
536--*/\r
537{\r
538 EFI_DATA_ENTRY *LogEntry;\r
539 LIST_ENTRY *Link;\r
540 BOOLEAN ReturnFirstEntry;\r
541 EFI_DATA_RECORD_HEADER *Record;\r
542 EFI_DATA_ENTRY *NextLogEntry;\r
543\r
544 //\r
545 // If MonotonicCount == 0 just return the first one\r
546 //\r
547 ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0);\r
548\r
549 Record = NULL;\r
550 for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
551 LogEntry = DATA_ENTRY_FROM_LINK (Link);\r
552 if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {\r
553 //\r
554 // Skip any entry that does not have the correct ClassFilter\r
555 //\r
556 continue;\r
557 }\r
558\r
559 if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {\r
560 //\r
561 // Return record to the user\r
562 //\r
563 Record = LogEntry->Record;\r
564\r
565 //\r
566 // Calculate the next MTC value. If there is no next entry set\r
567 // MTC to zero.\r
568 //\r
569 *PtrCurrentMTC = 0;\r
570 for (Link = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
571 NextLogEntry = DATA_ENTRY_FROM_LINK (Link);\r
572 if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {\r
573 //\r
574 // Return the MTC of the next thing to search for if found\r
575 //\r
576 *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;\r
577 break;\r
578 }\r
579 }\r
580 //\r
581 // Record found exit loop and return\r
582 //\r
583 break;\r
584 }\r
585 }\r
586\r
587 return Record;\r
588}\r
589//\r
590// Module Global:\r
591// Since this driver will only ever produce one instance of the Logging Hub\r
592// protocol you are not required to dynamically allocate the PrivateData.\r
593//\r
594DATA_HUB_INSTANCE mPrivateData;\r
595\r
596EFI_STATUS\r
597EFIAPI\r
598DataHubInstall (\r
599 IN EFI_HANDLE ImageHandle,\r
600 IN EFI_SYSTEM_TABLE *SystemTable\r
601 )\r
602/*++\r
603\r
604Routine Description:\r
605 Install Driver to produce Data Hub protocol. \r
606\r
607Arguments:\r
608 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
609\r
610Returns: \r
611\r
612 EFI_SUCCESS - Logging Hub protocol installed\r
613\r
614 Other - No protocol installed, unload driver.\r
615\r
616--*/\r
617{\r
618 EFI_STATUS Status;\r
619 UINT32 HighMontonicCount;\r
620\r
621 mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE;\r
622 mPrivateData.DataHub.LogData = DataHubLogData;\r
623 mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord;\r
624 mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver;\r
625 mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;\r
626\r
627 //\r
628 // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is\r
629 // required by this protocol\r
630 //\r
631 InitializeListHead (&mPrivateData.DataListHead);\r
632 InitializeListHead (&mPrivateData.FilterDriverListHead);\r
633\r
634 EfiInitializeLock (&mPrivateData.DataLock, EFI_TPL_NOTIFY);\r
635\r
636 //\r
637 // Make sure we get a bigger MTC number on every boot!\r
638 //\r
639 Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);\r
640 if (EFI_ERROR (Status)) {\r
641 //\r
642 // if system service fails pick a sane value.\r
643 //\r
644 mPrivateData.GlobalMonotonicCount = 0;\r
645 } else {\r
646 mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);\r
647 }\r
648 //\r
649 // Make a new handle and install the protocol\r
650 //\r
651 mPrivateData.Handle = NULL;\r
652 Status = gBS->InstallProtocolInterface (\r
653 &mPrivateData.Handle,\r
654 &gEfiDataHubProtocolGuid,\r
655 EFI_NATIVE_INTERFACE,\r
656 &mPrivateData.DataHub\r
657 );\r
658 return Status;\r
659}\r