/** Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This handler reads the Data Hub and sends any DEBUG info to StdErr. @param Event The event that occured, not used @param Context DataHub Protocol Pointer **/ VOID EFIAPI DataHubStdErrEventHandler ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_DATA_HUB_PROTOCOL *DataHub; EFI_DATA_RECORD_HEADER *Record; DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord; UINT64 Mtc; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto; INT32 OldAttribute; DataHub = (EFI_DATA_HUB_PROTOCOL *) Context; // // If StdErr is not yet initialized just return a DEBUG print in the BDS // after consoles are connect will make sure data gets flushed properly // when StdErr is available. // if (gST == NULL) { return ; } if (gST->StdErr == NULL) { return ; } // // Mtc of zero means return the next record that has not been read by the // event handler. // Mtc = 0; do { Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record); if (!EFI_ERROR (Status)) { if (CompareGuid (&Record->DataRecordGuid, &gEfiDataHubStatusCodeRecordGuid)) { DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize); if (DataRecord->Data.HeaderSize > 0) { if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) { // // If the Data record is from a DEBUG () then send it to Standard Error // Sto = gST->StdErr; OldAttribute = Sto->Mode->Attribute; Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK)); Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1)); Sto->SetAttribute (Sto, OldAttribute); } } } } } while ((Mtc != 0) && !EFI_ERROR (Status)); }
/** Smbios data filter function. This function is invoked when there is data records available in the Data Hub. @param Event The event that is signaled. @param Context not used here. **/ VOID EFIAPI SmbiosDataFilter ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_DATA_HUB_PROTOCOL *DataHub; EFI_HANDLE DataHubHandle; UINTN HandleSize; UINT64 MonotonicCount; EFI_DATA_RECORD_HEADER *Record; Status = EFI_SUCCESS; DataHub = NULL; // // Get the Data Hub Protocol. Assume only one instance // of Data Hub Protocol is availabe in the system. // HandleSize = sizeof (EFI_HANDLE); Status = gBS->LocateHandle ( ByProtocol, &gEfiDataHubProtocolGuid, NULL, &HandleSize, &DataHubHandle ); if (EFI_ERROR (Status)) { goto Done; } Status = gBS->HandleProtocol ( DataHubHandle, &gEfiDataHubProtocolGuid, (VOID **) &DataHub ); if (EFI_ERROR (Status)) { goto Done; } // // Get all available data records from data hub // MonotonicCount = 0; Record = NULL; do { Status = DataHub->GetNextRecord ( DataHub, &MonotonicCount, &Event, &Record ); if (!EFI_ERROR (Status)) { if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) { // // It's of expected Data Type. Process it. // SmbiosProcessDataRecord (Record); } } } while (!EFI_ERROR (Status) && (MonotonicCount != 0)); Done: return ; }
VOID EFIAPI WinNtIoProtocolNotifyFunction ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: This function will log memory size data to data hub. Arguments: Event - Event whose notification function is being invoked. Context - Pointer to the notification function's context. Returns: EFI_STATUS. --*/ { EFI_STATUS Status; EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData; EFI_DATA_RECORD_HEADER *Record; EFI_SUBCLASS_TYPE1_HEADER *DataHeader; UINTN HandleCount; UINTN HandleIndex; UINT64 MonotonicCount; BOOLEAN RecordFound; EFI_HANDLE *HandleBuffer; EFI_WIN_NT_IO_PROTOCOL *WinNtIo; EFI_DATA_HUB_PROTOCOL *DataHub; UINT64 TotalMemorySize; DataHub = NULL; MonotonicCount = 0; RecordFound = FALSE; // // Retrieve the list of all handles from the handle database. // Status = gBS->LocateHandleBuffer ( AllHandles, &gEfiWinNtIoProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { return ; } // // Locate DataHub protocol. // Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub); if (EFI_ERROR (Status)) { return ; } // // Search the Handle array to find the meory size information. // for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { Status = gBS->OpenProtocol ( HandleBuffer[HandleIndex], &gEfiWinNtIoProtocolGuid, &WinNtIo, Context, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { continue; } if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) && EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtMemoryGuid) ) { // // Check if this record has been stored in data hub. // do { Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record); if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) { DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1); if (EfiCompareGuid (&Record->DataRecordGuid, &gProcessorSubClassName) && (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER) ) { RecordFound = TRUE; } } } while (MonotonicCount != 0); if (RecordFound) { RecordFound = FALSE; continue; } // // Initialize data record. // MemorySubClassData.Header.Instance = 1; MemorySubClassData.Header.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE; MemorySubClassData.Header.RecordType = EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER; TotalMemorySize = (UINT64) Atoi (WinNtIo->EnvString); MemorySubClassData.Record.ArrayStartAddress.MemoryArrayStartAddress = 0; MemorySubClassData.Record.ArrayStartAddress.MemoryArrayEndAddress = LShiftU64 (TotalMemorySize, 20) - 1; MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.ProducerName = gMemoryProducerGuid; MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.Instance = 1; MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE; MemorySubClassData.Record.ArrayStartAddress.MemoryArrayPartitionWidth = 0; // // Store memory size data record to data hub. // Status = DataHub->LogData ( DataHub, &gEfiMemorySubClassGuid, &gMemoryProducerGuid, EFI_DATA_RECORD_CLASS_DATA, &MemorySubClassData, sizeof (EFI_SUBCLASS_TYPE1_HEADER) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS) ); } gBS->CloseProtocol ( HandleBuffer[HandleIndex], &gEfiWinNtIoProtocolGuid, Context, NULL ); } }