EFI_STATUS GetCurrentLanguage ( OUT CHAR16 *Lang ) /*++ Routine Description: Determine what is the current language setting Arguments: Lang - Pointer of system language Returns: Status code --*/ { EFI_STATUS Status; UINTN Size; UINTN Index; CHAR8 Language[4]; // // Getting the system language and placing it into our Global Data // Size = sizeof (Language); Status = gRT->GetVariable ( L"Lang", &gEfiGlobalVariableGuid, NULL, &Size, Language ); if (EFI_ERROR (Status)) { EfiAsciiStrCpy (Language, "eng"); } for (Index = 0; Index < 3; Index++) { // // Bitwise AND ascii value with 0xDF yields an uppercase value. // Sign extend into a unicode value // Lang[Index] = (CHAR16) (Language[Index] & 0xDF); } // // Null-terminate the value // Lang[3] = (CHAR16) 0; return Status; }
STATIC VOID GetNameFromHandle ( IN EFI_HANDLE Handle, OUT CHAR8 *GaugeString ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *Image; CHAR8 *PdbFileName; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; EfiAsciiStrCpy (GaugeString, " "); // // Get handle name from image protocol // Status = gBS->HandleProtocol ( Handle, &gEfiLoadedImageProtocolGuid, (VOID**)&Image ); if (EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Handle, &gEfiDriverBindingProtocolGuid, (VOID **) &DriverBinding, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return ; } // // Get handle name from image protocol // Status = gBS->HandleProtocol ( DriverBinding->ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Image ); } PdbFileName = GetPdbPath (Image->ImageBase); if (PdbFileName != NULL) { GetShortPdbFileName (PdbFileName, GaugeString); } return ; }
STATIC VOID GetShortPdbFileName ( CHAR8 *PdbFileName, CHAR8 *GaugeString ) /*++ Routine Description: Arguments: Returns: --*/ { UINTN Index; UINTN Index1; UINTN StartIndex; UINTN EndIndex; if (PdbFileName == NULL) { EfiAsciiStrCpy (GaugeString, " "); } else { StartIndex = 0; for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) ; for (Index = 0; PdbFileName[Index] != 0; Index++) { if (PdbFileName[Index] == '\\') { StartIndex = Index + 1; } if (PdbFileName[Index] == '.') { EndIndex = Index; } } Index1 = 0; for (Index = StartIndex; Index < EndIndex; Index++) { GaugeString[Index1] = PdbFileName[Index]; Index1++; if (Index1 == EFI_PERF_PDBFILENAME_LENGTH - 1) { break; } } GaugeString[Index1] = 0; } return ; }
VOID EfiAsciiStrCat ( IN CHAR8 *Destination, IN CHAR8 *Source ) /*++ Routine Description: Concatinate Source on the end of Destination Arguments: Destination - String to added to the end of. Source - String to concatinate. Returns: NONE --*/ { EfiAsciiStrCpy (Destination + EfiAsciiStrLen (Destination), Source); }
VOID WriteBootToOsPerformanceData ( VOID ) /*++ Routine Description: Allocates a block of memory and writes performance data of booting to OS into it. Arguments: None Returns: None --*/ { EFI_STATUS Status; EFI_CPU_ARCH_PROTOCOL *Cpu; EFI_PERFORMANCE_PROTOCOL *DrvPerf; UINT32 mAcpiLowMemoryLength; UINT32 LimitCount; EFI_PERF_HEADER mPerfHeader; EFI_PERF_DATA mPerfData; EFI_GAUGE_DATA *DumpData; EFI_HANDLE *Handles; UINTN NoHandles; UINT8 *Ptr; UINT8 *PdbFileName; UINT32 mIndex; UINT64 Ticker; UINT64 Freq; UINT32 Duration; UINT64 CurrentTicker; UINT64 TimerPeriod; // // Retrive time stamp count as early as possilbe // Ticker = EfiReadTsc (); // // Get performance architecture protocol // Status = gBS->LocateProtocol ( &gEfiPerformanceProtocolGuid, NULL, &DrvPerf ); if (EFI_ERROR (Status)) { return ; } // // Get CPU frequency // Status = gBS->LocateProtocol ( &gEfiCpuArchProtocolGuid, NULL, &Cpu ); if (EFI_ERROR (Status)) { return ; } // // Get Cpu Frequency // Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod); if (EFI_ERROR (Status)) { return ; } // // Put Detailed performance data into memory // Handles = NULL; Status = gBS->LocateHandleBuffer ( AllHandles, NULL, NULL, &NoHandles, &Handles ); if (EFI_ERROR (Status)) { return ; } // // Allocate a block of memory that contain performance data to OS // if it is not allocated yet. // if (mAcpiLowMemoryBase == 0x0FFFFFFFF) { Status = gBS->AllocatePages ( AllocateMaxAddress, EfiReservedMemoryType, 4, &mAcpiLowMemoryBase ); if (EFI_ERROR (Status)) { gBS->FreePool (Handles); return ; } } mAcpiLowMemoryLength = EFI_PAGES_TO_SIZE(4); Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (EFI_PERF_HEADER)); LimitCount = (mAcpiLowMemoryLength - sizeof (EFI_PERF_HEADER)) / sizeof (EFI_PERF_DATA); // // Initialize performance data structure // EfiZeroMem (&mPerfHeader, sizeof (EFI_PERF_HEADER)); Freq = DivU64x32 (1000000000000, (UINTN) TimerPeriod, NULL); mPerfHeader.CpuFreq = Freq; // // Record BDS raw performance data // mPerfHeader.BDSRaw = Ticker; // // Get DXE drivers performance // for (mIndex = 0; mIndex < NoHandles; mIndex++) { Ticker = 0; PdbFileName = NULL; DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host NULL // PrecGauge ); while (DumpData) { if (DumpData->Handle == Handles[mIndex]) { PdbFileName = &(DumpData->PdbFileName[0]); if (DumpData->StartTick < DumpData->EndTick) { Ticker += (DumpData->EndTick - DumpData->StartTick); } } DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); } Duration = (UINT32) DivU64x32 ( Ticker, (UINT32) Freq, NULL ); if (Duration > 0) { EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA)); if (PdbFileName != NULL) { EfiAsciiStrCpy (mPerfData.Token, PdbFileName); } mPerfData.Duration = Duration; EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA)); Ptr += sizeof (EFI_PERF_DATA); mPerfHeader.Count++; if (mPerfHeader.Count == LimitCount) { goto Done; } } } gBS->FreePool (Handles); // // Get inserted performance data // DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host NULL // PrecGauge ); while (DumpData) { if ((DumpData->Handle) || (DumpData->StartTick > DumpData->EndTick)) { DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); continue; } EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA)); ConvertChar16ToChar8 ((UINT8 *) mPerfData.Token, DumpData->Token); mPerfData.Duration = (UINT32) DivU64x32 ( DumpData->EndTick - DumpData->StartTick, (UINT32) Freq, NULL ); EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA)); Ptr += sizeof (EFI_PERF_DATA); mPerfHeader.Count++; if (mPerfHeader.Count == LimitCount) { goto Done; } DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); } Done: mPerfHeader.Signiture = 0x66726550; // // Put performance data to memory // EfiCopyMem ( (UINTN *) (UINTN) mAcpiLowMemoryBase, &mPerfHeader, sizeof (EFI_PERF_HEADER) ); gRT->SetVariable ( L"PerfDataMemAddr", &gEfiGenericVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT32), (VOID *) &mAcpiLowMemoryBase ); return ; }
EFI_STATUS EfiDebugAssertWorker ( IN CHAR8 *Filename, IN INTN LineNumber, IN CHAR8 *Description, IN UINTN BufferSize, IN OUT VOID *Buffer ) /*++ Routine Description: Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT information. If Error Logging hub is not loaded DEADLOOP (). We use UINT64 buffers due to IPF alignment concerns. Arguments: Filename - File name of failing routine. LineNumber - Line number of failing ASSERT(). Description - Description, usually the assertion, BufferSize - Size of Buffer. Buffer - Caller allocated buffer, contains ReportStatusCode extendecd data Returns: Status code EFI_BUFFER_TOO_SMALL - Buffer not large enough EFI_SUCCESS - Function successfully done. --*/ { EFI_DEBUG_ASSERT_DATA *AssertData; UINTN TotalSize; CHAR8 *EndOfStr; // // Make sure it will all fit in the passed in buffer // TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA); TotalSize += EfiAsciiStrLen (Filename); TotalSize += EfiAsciiStrLen (Description); if (TotalSize > BufferSize) { return EFI_BUFFER_TOO_SMALL; } // // Fill in EFI_STATUS_CODE_DATA // AssertData = (EFI_DEBUG_ASSERT_DATA *) EfiConstructStatusCodeData ( (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)), &gEfiStatusCodeDataTypeAssertGuid, Buffer ); // // Fill in EFI_DEBUG_ASSERT_DATA // AssertData->LineNumber = (UINT32)LineNumber; // // Copy Ascii FileName including NULL. // EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename); // // Copy Ascii Description // EfiAsciiStrCpy (EndOfStr, Description); return EFI_SUCCESS; }