diff options
Diffstat (limited to 'ShellPkg/DynamicCommand')
33 files changed, 9038 insertions, 9038 deletions
diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c index 98c84d2ef9..c1d194ab03 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c @@ -1,1031 +1,1031 @@ -/** @file
- Shell command for Displaying Performance Metrics.
-
- The Dp command reads performance data and presents it in several
- different formats depending upon the needs of the user. Both
- Trace and Measured Profiling information is processed and presented.
-
- Dp uses the "PerformanceLib" to read the measurement records.
- The "TimerLib" provides information about the timer, such as frequency,
- beginning, and ending counter values.
- Measurement records contain identifying information (Handle, Token, Module)
- and start and end time values.
- Dp uses this information to group records in different ways. It also uses
- timer information to calculate elapsed time for each measurement.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include "Dp.h"
-#include "Literals.h"
-#include "DpInternal.h"
-
-#pragma pack(1)
-
-typedef struct {
- EFI_ACPI_DESCRIPTION_HEADER Header;
- UINT32 Entry;
-} RSDT_TABLE;
-
-typedef struct {
- EFI_ACPI_DESCRIPTION_HEADER Header;
- UINT64 Entry;
-} XSDT_TABLE;
-
-#pragma pack()
-
-EFI_HII_HANDLE mDpHiiHandle;
-
-typedef struct {
- EFI_HANDLE Handle;
- EFI_GUID ModuleGuid;
-} HANDLE_GUID_MAP;
-
-HANDLE_GUID_MAP *mCacheHandleGuidTable;
-UINTN mCachePairCount = 0;
-
-//
-/// Module-Global Variables
-///@{
-CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
-CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
-UINT64 mInterestThreshold;
-BOOLEAN mShowId = FALSE;
-UINT8 *mBootPerformanceTable;
-UINTN mBootPerformanceTableSize;
-BOOLEAN mPeiPhase = FALSE;
-BOOLEAN mDxePhase = FALSE;
-UINT64 mResetEnd = 0;
-
-PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
-MEASUREMENT_RECORD *mMeasurementList = NULL;
-UINTN mMeasurementNum = 0;
-
-/// Items for which to gather cumulative statistics.
-PERF_CUM_DATA CumData[] = {
- PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
- PERF_INIT_CUM_DATA (START_IMAGE_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK)
-};
-
-/// Number of items for which we are gathering cumulative statistics.
-UINT32 const NumCum = sizeof (CumData) / sizeof (PERF_CUM_DATA);
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-v", TypeFlag }, // -v Verbose Mode
- { L"-A", TypeFlag }, // -A All, Cooked
- { L"-R", TypeFlag }, // -R RAW All
- { L"-s", TypeFlag }, // -s Summary
- { L"-x", TypeFlag }, // -x eXclude Cumulative Items
- { L"-i", TypeFlag }, // -i Display Identifier
- { L"-c", TypeValue }, // -c Display cumulative data.
- { L"-n", TypeValue }, // -n # Number of records to display for A and R
- { L"-t", TypeValue }, // -t # Threshold of interest
- { NULL, TypeMax }
-};
-
-///@}
-
-/**
- Display the trailing Verbose information.
-**/
-VOID
-DumpStatistics (
- void
- )
-{
- EFI_STRING StringPtr;
- EFI_STRING StringPtrUnknown;
-
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal);
- SHELL_FREE_NON_NULL (StringPtr);
- SHELL_FREE_NON_NULL (StringPtrUnknown);
-}
-
-/**
- Get Boot performance table form Acpi table.
-
-**/
-EFI_STATUS
-GetBootPerformanceTable (
- )
-{
- EFI_STATUS Status;
- FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;
-
- FirmwarePerformanceTable = (FIRMWARE_PERFORMANCE_TABLE *)EfiLocateFirstAcpiTable (
- EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
- );
- if (FirmwarePerformanceTable == NULL) {
- Status = EfiGetSystemConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID **)&mBootPerformanceTable);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);
- return EFI_NOT_FOUND;
- }
- } else {
- mBootPerformanceTable = (UINT8 *)(UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
- }
-
- mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *)mBootPerformanceTable)->Header.Length;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Handle form Module Guid.
-
- @param ModuleGuid Module Guid.
- @param Handle The handle to be returned.
-
-**/
-VOID
-GetHandleFormModuleGuid (
- IN EFI_GUID *ModuleGuid,
- IN OUT EFI_HANDLE *Handle
- )
-{
- UINTN Index;
-
- if (IsZeroGuid (ModuleGuid)) {
- *Handle = NULL;
- }
-
- //
- // Try to get the Handle from the cached array.
- //
- for (Index = 0; Index < mCachePairCount; Index++) {
- if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
- *Handle = mCacheHandleGuidTable[Index].Handle;
- break;
- }
- }
-
- if (Index >= mCachePairCount) {
- *Handle = NULL;
- }
-}
-
-/**
-Cache the GUID and handle mapping pairs. In order to save time for searching.
-
-**/
-EFI_STATUS
-BuildCachedGuidHandleTable (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
- EFI_GUID *TempGuid;
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
-
- Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
- return Status;
- }
-
- mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
- if (mCacheHandleGuidTable == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- //
- // Try Handle as ImageHandle.
- //
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- if (EFI_ERROR (Status)) {
- //
- // Try Handle as Controller Handle
- //
- Status = gBS->OpenProtocol (
- HandleBuffer[Index],
- &gEfiDriverBindingProtocolGuid,
- (VOID **)&DriverBinding,
- NULL,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- //
- // Get Image protocol from ImageHandle
- //
- Status = gBS->HandleProtocol (
- DriverBinding->ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- }
- }
-
- if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
- //
- // Get Module Guid from DevicePath.
- //
- if ((LoadedImage->FilePath != NULL) &&
- (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
- (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
- )
- {
- FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
- TempGuid = &FvFilePath->FvFileName;
-
- mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
- CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
- mCachePairCount++;
- }
- }
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- HandleBuffer = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Measurement form Fpdt records.
-
- @param RecordHeader Pointer to the start record.
- @param IsStart Is start record or End record.
- @param Measurement Pointer to the measurement which need to be filled.
-
-**/
-VOID
-GetMeasurementInfo (
- IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader,
- IN BOOLEAN IsStart,
- IN OUT MEASUREMENT_RECORD *Measurement
- )
-{
- VOID *ModuleGuid;
- EFI_HANDLE StartHandle;
-
- switch (RecordHeader->Type) {
- case FPDT_GUID_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_START_ID:
- case MODULE_END_ID:
- if (mPeiPhase) {
- Measurement->Token = ALit_PEIM;
- Measurement->Module = ALit_PEIM;
- } else if (mDxePhase) {
- Measurement->Token = ALit_START_IMAGE;
- Measurement->Module = ALit_START_IMAGE;
- }
-
- break;
- default:
- ASSERT (FALSE);
- }
-
- if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
- Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- } else {
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- //
- // When no perf entry to record the PEI and DXE phase,
- // For start image, we need detect the PEIM and non PEIM here.
- //
- if (Measurement->Token == NULL) {
- if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
- Measurement->Token = ALit_PEIM;
- Measurement->Module = ALit_PEIM;
- Measurement->Handle = ModuleGuid;
- } else {
- Measurement->Token = ALit_START_IMAGE;
- Measurement->Module = ALit_START_IMAGE;
- }
- }
- }
-
- break;
-
- case FPDT_DYNAMIC_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_START_ID:
- case MODULE_END_ID:
- if (mPeiPhase) {
- Measurement->Token = ALit_PEIM;
- } else if (mDxePhase) {
- Measurement->Token = ALit_START_IMAGE;
- }
-
- break;
-
- case MODULE_LOADIMAGE_START_ID:
- case MODULE_LOADIMAGE_END_ID:
- Measurement->Token = ALit_LOAD_IMAGE;
- break;
-
- case MODULE_DB_START_ID:
- case MODULE_DB_END_ID:
- Measurement->Token = ALit_DB_START;
- break;
-
- case MODULE_DB_SUPPORT_START_ID:
- case MODULE_DB_SUPPORT_END_ID:
- Measurement->Token = ALit_DB_SUPPORT;
- break;
-
- case MODULE_DB_STOP_START_ID:
- case MODULE_DB_STOP_END_ID:
- Measurement->Token = ALit_DB_STOP;
- break;
-
- default:
- Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
- break;
- }
-
- Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
-
- if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
- Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- } else {
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- //
- // When no perf entry to record the PEI and DXE phase,
- // For start image, we need detect the PEIM and non PEIM here.
- //
- if ((Measurement->Token == NULL) && ((Measurement->Identifier == MODULE_START_ID) || (Measurement->Identifier == MODULE_END_ID))) {
- if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
- Measurement->Token = ALit_PEIM;
- Measurement->Handle = ModuleGuid;
- } else {
- Measurement->Token = ALit_START_IMAGE;
- }
- }
- }
-
- break;
-
- case FPDT_GUID_QWORD_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_DB_START_ID:
- Measurement->Token = ALit_DB_START;
- Measurement->Module = ALit_DB_START;
- break;
-
- case MODULE_DB_SUPPORT_START_ID:
- case MODULE_DB_SUPPORT_END_ID:
- Measurement->Token = ALit_DB_SUPPORT;
- Measurement->Module = ALit_DB_SUPPORT;
- break;
-
- case MODULE_DB_STOP_START_ID:
- case MODULE_DB_STOP_END_ID:
- Measurement->Token = ALit_DB_STOP;
- Measurement->Module = ALit_DB_STOP;
- break;
-
- case MODULE_LOADIMAGE_START_ID:
- case MODULE_LOADIMAGE_END_ID:
- Measurement->Token = ALit_LOAD_IMAGE;
- Measurement->Module = ALit_LOAD_IMAGE;
- break;
-
- default:
- ASSERT (FALSE);
- }
-
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- case FPDT_GUID_QWORD_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- //
- // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
- //
- switch (Measurement->Identifier) {
- case MODULE_DB_END_ID:
- Measurement->Token = ALit_DB_START;
- Measurement->Module = ALit_DB_START;
- break;
- default:
- ASSERT (FALSE);
- }
-
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
- Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
- Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Search the start measurement in the mMeasurementList for the end measurement.
-
- @param EndMeasureMent Measurement for end record.
-
-**/
-VOID
-SearchMeasurement (
- IN MEASUREMENT_RECORD *EndMeasureMent
- )
-{
- INTN Index;
-
- for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
- if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
- if ((mMeasurementList[Index].EndTimeStamp == 0) && (EndMeasureMent->Handle != NULL) && (mMeasurementList[Index].Handle != NULL) &&
- CompareGuid (mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
- if ((mMeasurementList[Index].EndTimeStamp == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
- (mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- } else {
- if ((mMeasurementList[Index].EndTimeStamp == 0) && (mMeasurementList[Index].Handle == EndMeasureMent->Handle) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- }
- }
-}
-
-/**
- Generate the measure record array.
-
-**/
-EFI_STATUS
-BuildMeasurementList (
- )
-{
- EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;
- UINT8 *PerformanceTablePtr;
- UINT8 *BasicBootTablePtr;
- UINT64 ResetEnd;
- UINT16 StartProgressId;
- UINTN TableLength;
- UINT8 *StartRecordEvent;
- MEASUREMENT_RECORD MeasureMent;
-
- mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
- if (mMeasurementList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Update the ResetEnd which was logged at the beginning of firmware image execution
- //
- TableLength = sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER);
- BasicBootTablePtr = (mBootPerformanceTable + TableLength);
- ResetEnd = ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)BasicBootTablePtr)->ResetEnd;
-
- if (ResetEnd > 0) {
- mResetEnd = ResetEnd;
- }
-
- TableLength = sizeof (BOOT_PERFORMANCE_TABLE);
- PerformanceTablePtr = (mBootPerformanceTable + TableLength);
-
- while (TableLength < mBootPerformanceTableSize) {
- RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)PerformanceTablePtr;
- StartRecordEvent = (UINT8 *)RecordHeader;
- StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
-
- //
- // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0.
- // If the record is the start record, fill the info to the measurement in the mMeasurementList.
- // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
- //
- if (StartProgressId == 0) {
- GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
- mMeasurementNum++;
- } else if ((((StartProgressId >= PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x000F) == 0)) ||
- ((StartProgressId < PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x0001) != 0))))
- {
- //
- // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
- // So we need to identify these two kinds of record through different phase.
- //
- if (StartProgressId == PERF_CROSSMODULE_START_ID ) {
- if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
- mPeiPhase = TRUE;
- } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
- mDxePhase = TRUE;
- mPeiPhase = FALSE;
- }
- }
-
- // Get measurement info form the start record to the mMeasurementList.
- GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
- mMeasurementNum++;
- } else {
- ZeroMem (&MeasureMent, sizeof (MEASUREMENT_RECORD));
- GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
- SearchMeasurement (&MeasureMent);
- }
-
- TableLength += RecordHeader->Length;
- PerformanceTablePtr += RecordHeader->Length;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Initialize the cumulative data.
-
-**/
-VOID
-InitCumulativeData (
- VOID
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < NumCum; ++Index) {
- CumData[Index].Count = 0;
- CumData[Index].MinDur = PERF_MAXDUR;
- CumData[Index].MaxDur = 0;
- CumData[Index].Duration = 0;
- }
-}
-
-/**
- Initialize the Summary data.
-
-**/
-VOID
-InitSummaryData (
- VOID
- )
-{
- SummaryData.NumTrace = 0;
- SummaryData.NumIncomplete = 0;
- SummaryData.NumSummary = 0;
- SummaryData.NumHandles = 0;
- SummaryData.NumPEIMs = 0;
- SummaryData.NumGlobal = 0;
-}
-
-/**
- Dump performance data.
-
- @param[in] ImageHandle The image handle.
- @param[in] SystemTable The system table.
-
- @retval SHELL_SUCCESS Command completed successfully.
- @retval SHELL_INVALID_PARAMETER Command usage error.
- @retval SHELL_ABORTED The user aborts the operation.
- @retval value Unknown error.
-**/
-SHELL_STATUS
-RunDp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- LIST_ENTRY *ParamPackage;
- CONST CHAR16 *CmdLineArg;
- EFI_STATUS Status;
-
- PERFORMANCE_PROPERTY *PerformanceProperty;
- UINTN Number2Display;
-
- EFI_STRING StringPtr;
- BOOLEAN SummaryMode;
- BOOLEAN VerboseMode;
- BOOLEAN AllMode;
- BOOLEAN RawMode;
- BOOLEAN ExcludeMode;
- BOOLEAN CumulativeMode;
- CONST CHAR16 *CustomCumulativeToken;
- PERF_CUM_DATA *CustomCumulativeData;
- UINTN NameSize;
- SHELL_STATUS ShellStatus;
- TIMER_INFO TimerInfo;
- UINT64 Intermediate;
-
- StringPtr = NULL;
- SummaryMode = FALSE;
- VerboseMode = FALSE;
- AllMode = FALSE;
- RawMode = FALSE;
- ExcludeMode = FALSE;
- CumulativeMode = FALSE;
- CustomCumulativeData = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Process Command Line arguments
- //
- Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount (ParamPackage) > 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- }
-
- //
- // Boolean options
- //
- VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
- SummaryMode = (BOOLEAN)(ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
- AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");
- RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");
- ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
- mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
- CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");
-
- if (AllMode && RawMode) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");
- return SHELL_INVALID_PARAMETER;
- }
-
- // Options with Values
- if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {
- CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
- if (CmdLineArg == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- if (!(RawMode || AllMode)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- }
-
- Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");
- return SHELL_INVALID_PARAMETER;
- } else {
- Number2Display = (UINTN)Intermediate;
- if ((Number2Display == 0) || (Number2Display > MAXIMUM_DISPLAYCOUNT)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);
- return SHELL_INVALID_PARAMETER;
- }
- }
- }
- } else {
- Number2Display = DEFAULT_DISPLAYCOUNT;
- }
-
- if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {
- CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
- if (CmdLineArg == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");
- return SHELL_INVALID_PARAMETER;
- } else {
- mInterestThreshold = Intermediate;
- }
- }
- } else {
- mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
- }
-
- if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
- CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");
- if (CustomCumulativeToken == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
- if (CustomCumulativeData == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- CustomCumulativeData->MinDur = PERF_MAXDUR;
- CustomCumulativeData->MaxDur = 0;
- CustomCumulativeData->Count = 0;
- CustomCumulativeData->Duration = 0;
- NameSize = StrLen (CustomCumulativeToken) + 1;
- CustomCumulativeData->Name = AllocateZeroPool (NameSize);
- if (CustomCumulativeData->Name == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);
- }
- }
-
- //
- // DP dump performance data by parsing FPDT table in ACPI table.
- // Folloing 3 steps are to get the measurement form the FPDT table.
- //
-
- //
- // 1. Get FPDT from ACPI table.
- //
- Status = GetBootPerformanceTable ();
- if (EFI_ERROR (Status)) {
- ShellStatus = Status;
- goto Done;
- }
-
- //
- // 2. Cache the ModuleGuid and hanlde mapping table.
- //
- Status = BuildCachedGuidHandleTable ();
- if (EFI_ERROR (Status)) {
- ShellStatus = Status;
- goto Done;
- }
-
- //
- // 3. Build the measurement array form the FPDT records.
- //
- Status = BuildMeasurementList ();
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- //
- // Initialize the pre-defined cumulative data.
- //
- InitCumulativeData ();
-
- //
- // Initialize the Summary data.
- //
- InitSummaryData ();
-
- //
- // Timer specific processing
- //
- // Get the Performance counter characteristics:
- // Freq = Frequency in Hz
- // StartCount = Value loaded into the counter when it starts counting
- // EndCount = Value counter counts to before it needs to be reset
- //
- Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
- if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);
- goto Done;
- }
-
- TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
- TimerInfo.StartCount = 0;
- TimerInfo.EndCount = 0xFFFF;
- TimerInfo.CountUp = TRUE;
-
- //
- // Print header
- //
- // print DP's build version
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
-
- // print performance timer characteristics
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);
-
- if (VerboseMode && !RawMode) {
- StringPtr = HiiGetString (
- mDpHiiHandle,
- (EFI_STRING_ID)(TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
- NULL
- );
- ASSERT (StringPtr != NULL);
- // Print Timer count range and direction
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_TIMER_PROPERTIES),
- mDpHiiHandle,
- StringPtr,
- TimerInfo.StartCount,
- TimerInfo.EndCount
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);
- }
-
- /****************************************************************************
- **** Print Sections based on command line options
- ****
- **** Option modes have the following priority:
- **** v Verbose -- Valid in combination with any other options
- **** t Threshold -- Modifies All, Raw, and Cooked output
- **** Default is 0 for All and Raw mode
- **** Default is DEFAULT_THRESHOLD for "Cooked" mode
- **** n Number2Display Used by All and Raw mode. Otherwise ignored.
- **** A All -- R and S options are ignored
- **** R Raw -- S option is ignored
- **** s Summary -- Modifies "Cooked" output only
- **** Cooked (Default)
- ****************************************************************************/
- GatherStatistics (CustomCumulativeData);
- if (CumulativeMode) {
- ProcessCumulative (CustomCumulativeData);
- } else if (AllMode) {
- Status = DumpAllTrace (Number2Display, ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
- } else if (RawMode) {
- Status = DumpRawTrace (Number2Display, ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
- } else {
- // ------------- Begin Cooked Mode Processing
- ProcessPhases ();
- if ( !SummaryMode) {
- Status = ProcessHandles (ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- Status = ProcessPeims ();
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- Status = ProcessGlobal ();
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- ProcessCumulative (NULL);
- }
- } // ------------- End of Cooked Mode Processing
-
- if ( VerboseMode || SummaryMode) {
- DumpStatistics ();
- }
-
-Done:
- if (ParamPackage != NULL) {
- ShellCommandLineFreeVarList (ParamPackage);
- }
-
- SHELL_FREE_NON_NULL (StringPtr);
- if (CustomCumulativeData != NULL) {
- SHELL_FREE_NON_NULL (CustomCumulativeData->Name);
- }
-
- SHELL_FREE_NON_NULL (CustomCumulativeData);
-
- SHELL_FREE_NON_NULL (mMeasurementList);
-
- SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
-
- mMeasurementNum = 0;
- mCachePairCount = 0;
- return ShellStatus;
-}
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param ImageHandle The image handle of the process.
-
- @return HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Retrieve HII package list from ImageHandle
- //
- Status = gBS->OpenProtocol (
- ImageHandle,
- &gEfiHiiPackageListProtocolGuid,
- (VOID **)&PackageList,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Publish HII package list to HII Database.
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageList,
- NULL,
- &HiiHandle
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return HiiHandle;
-}
+/** @file + Shell command for Displaying Performance Metrics. + + The Dp command reads performance data and presents it in several + different formats depending upon the needs of the user. Both + Trace and Measured Profiling information is processed and presented. + + Dp uses the "PerformanceLib" to read the measurement records. + The "TimerLib" provides information about the timer, such as frequency, + beginning, and ending counter values. + Measurement records contain identifying information (Handle, Token, Module) + and start and end time values. + Dp uses this information to group records in different ways. It also uses + timer information to calculate elapsed time for each measurement. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. + (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Dp.h" +#include "Literals.h" +#include "DpInternal.h" + +#pragma pack(1) + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 Entry; +} RSDT_TABLE; + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT64 Entry; +} XSDT_TABLE; + +#pragma pack() + +EFI_HII_HANDLE mDpHiiHandle; + +typedef struct { + EFI_HANDLE Handle; + EFI_GUID ModuleGuid; +} HANDLE_GUID_MAP; + +HANDLE_GUID_MAP *mCacheHandleGuidTable; +UINTN mCachePairCount = 0; + +// +/// Module-Global Variables +///@{ +CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1]; +CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE]; +UINT64 mInterestThreshold; +BOOLEAN mShowId = FALSE; +UINT8 *mBootPerformanceTable; +UINTN mBootPerformanceTableSize; +BOOLEAN mPeiPhase = FALSE; +BOOLEAN mDxePhase = FALSE; +UINT64 mResetEnd = 0; + +PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO. +MEASUREMENT_RECORD *mMeasurementList = NULL; +UINTN mMeasurementNum = 0; + +/// Items for which to gather cumulative statistics. +PERF_CUM_DATA CumData[] = { + PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK), + PERF_INIT_CUM_DATA (START_IMAGE_TOK), + PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK), + PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK), + PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK) +}; + +/// Number of items for which we are gathering cumulative statistics. +UINT32 const NumCum = sizeof (CumData) / sizeof (PERF_CUM_DATA); + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-v", TypeFlag }, // -v Verbose Mode + { L"-A", TypeFlag }, // -A All, Cooked + { L"-R", TypeFlag }, // -R RAW All + { L"-s", TypeFlag }, // -s Summary + { L"-x", TypeFlag }, // -x eXclude Cumulative Items + { L"-i", TypeFlag }, // -i Display Identifier + { L"-c", TypeValue }, // -c Display cumulative data. + { L"-n", TypeValue }, // -n # Number of records to display for A and R + { L"-t", TypeValue }, // -t # Threshold of interest + { NULL, TypeMax } +}; + +///@} + +/** + Display the trailing Verbose information. +**/ +VOID +DumpStatistics ( + void + ) +{ + EFI_STRING StringPtr; + EFI_STRING StringPtrUnknown; + + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL); + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal); + SHELL_FREE_NON_NULL (StringPtr); + SHELL_FREE_NON_NULL (StringPtrUnknown); +} + +/** + Get Boot performance table form Acpi table. + +**/ +EFI_STATUS +GetBootPerformanceTable ( + ) +{ + EFI_STATUS Status; + FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable; + + FirmwarePerformanceTable = (FIRMWARE_PERFORMANCE_TABLE *)EfiLocateFirstAcpiTable ( + EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE + ); + if (FirmwarePerformanceTable == NULL) { + Status = EfiGetSystemConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID **)&mBootPerformanceTable); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle); + return EFI_NOT_FOUND; + } + } else { + mBootPerformanceTable = (UINT8 *)(UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer; + } + + mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *)mBootPerformanceTable)->Header.Length; + + return EFI_SUCCESS; +} + +/** + Get Handle form Module Guid. + + @param ModuleGuid Module Guid. + @param Handle The handle to be returned. + +**/ +VOID +GetHandleFormModuleGuid ( + IN EFI_GUID *ModuleGuid, + IN OUT EFI_HANDLE *Handle + ) +{ + UINTN Index; + + if (IsZeroGuid (ModuleGuid)) { + *Handle = NULL; + } + + // + // Try to get the Handle from the cached array. + // + for (Index = 0; Index < mCachePairCount; Index++) { + if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) { + *Handle = mCacheHandleGuidTable[Index].Handle; + break; + } + } + + if (Index >= mCachePairCount) { + *Handle = NULL; + } +} + +/** +Cache the GUID and handle mapping pairs. In order to save time for searching. + +**/ +EFI_STATUS +BuildCachedGuidHandleTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + EFI_GUID *TempGuid; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath; + + Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status); + return Status; + } + + mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP)); + if (mCacheHandleGuidTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < HandleCount; Index++) { + // + // Try Handle as ImageHandle. + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR (Status)) { + // + // Try Handle as Controller Handle + // + Status = gBS->OpenProtocol ( + HandleBuffer[Index], + &gEfiDriverBindingProtocolGuid, + (VOID **)&DriverBinding, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + // + // Get Image protocol from ImageHandle + // + Status = gBS->HandleProtocol ( + DriverBinding->ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + } + } + + if (!EFI_ERROR (Status) && (LoadedImage != NULL)) { + // + // Get Module Guid from DevicePath. + // + if ((LoadedImage->FilePath != NULL) && + (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) && + (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP) + ) + { + FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath; + TempGuid = &FvFilePath->FvFileName; + + mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index]; + CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid); + mCachePairCount++; + } + } + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + HandleBuffer = NULL; + } + + return EFI_SUCCESS; +} + +/** + Get Measurement form Fpdt records. + + @param RecordHeader Pointer to the start record. + @param IsStart Is start record or End record. + @param Measurement Pointer to the measurement which need to be filled. + +**/ +VOID +GetMeasurementInfo ( + IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader, + IN BOOLEAN IsStart, + IN OUT MEASUREMENT_RECORD *Measurement + ) +{ + VOID *ModuleGuid; + EFI_HANDLE StartHandle; + + switch (RecordHeader->Type) { + case FPDT_GUID_EVENT_TYPE: + ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid); + Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID); + if (IsStart) { + Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp; + } else { + Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp; + } + + switch (Measurement->Identifier) { + case MODULE_START_ID: + case MODULE_END_ID: + if (mPeiPhase) { + Measurement->Token = ALit_PEIM; + Measurement->Module = ALit_PEIM; + } else if (mDxePhase) { + Measurement->Token = ALit_START_IMAGE; + Measurement->Module = ALit_START_IMAGE; + } + + break; + default: + ASSERT (FALSE); + } + + if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) { + Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid); + } else { + GetHandleFormModuleGuid (ModuleGuid, &StartHandle); + Measurement->Handle = StartHandle; + // + // When no perf entry to record the PEI and DXE phase, + // For start image, we need detect the PEIM and non PEIM here. + // + if (Measurement->Token == NULL) { + if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) { + Measurement->Token = ALit_PEIM; + Measurement->Module = ALit_PEIM; + Measurement->Handle = ModuleGuid; + } else { + Measurement->Token = ALit_START_IMAGE; + Measurement->Module = ALit_START_IMAGE; + } + } + } + + break; + + case FPDT_DYNAMIC_STRING_EVENT_TYPE: + ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid); + Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID); + if (IsStart) { + Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } else { + Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } + + switch (Measurement->Identifier) { + case MODULE_START_ID: + case MODULE_END_ID: + if (mPeiPhase) { + Measurement->Token = ALit_PEIM; + } else if (mDxePhase) { + Measurement->Token = ALit_START_IMAGE; + } + + break; + + case MODULE_LOADIMAGE_START_ID: + case MODULE_LOADIMAGE_END_ID: + Measurement->Token = ALit_LOAD_IMAGE; + break; + + case MODULE_DB_START_ID: + case MODULE_DB_END_ID: + Measurement->Token = ALit_DB_START; + break; + + case MODULE_DB_SUPPORT_START_ID: + case MODULE_DB_SUPPORT_END_ID: + Measurement->Token = ALit_DB_SUPPORT; + break; + + case MODULE_DB_STOP_START_ID: + case MODULE_DB_STOP_END_ID: + Measurement->Token = ALit_DB_STOP; + break; + + default: + Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String; + break; + } + + Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String; + + if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) { + Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid); + } else { + GetHandleFormModuleGuid (ModuleGuid, &StartHandle); + Measurement->Handle = StartHandle; + // + // When no perf entry to record the PEI and DXE phase, + // For start image, we need detect the PEIM and non PEIM here. + // + if ((Measurement->Token == NULL) && ((Measurement->Identifier == MODULE_START_ID) || (Measurement->Identifier == MODULE_END_ID))) { + if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) { + Measurement->Token = ALit_PEIM; + Measurement->Handle = ModuleGuid; + } else { + Measurement->Token = ALit_START_IMAGE; + } + } + } + + break; + + case FPDT_GUID_QWORD_EVENT_TYPE: + ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid); + Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID); + if (IsStart) { + Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp; + } else { + Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp; + } + + switch (Measurement->Identifier) { + case MODULE_DB_START_ID: + Measurement->Token = ALit_DB_START; + Measurement->Module = ALit_DB_START; + break; + + case MODULE_DB_SUPPORT_START_ID: + case MODULE_DB_SUPPORT_END_ID: + Measurement->Token = ALit_DB_SUPPORT; + Measurement->Module = ALit_DB_SUPPORT; + break; + + case MODULE_DB_STOP_START_ID: + case MODULE_DB_STOP_END_ID: + Measurement->Token = ALit_DB_STOP; + Measurement->Module = ALit_DB_STOP; + break; + + case MODULE_LOADIMAGE_START_ID: + case MODULE_LOADIMAGE_END_ID: + Measurement->Token = ALit_LOAD_IMAGE; + Measurement->Module = ALit_LOAD_IMAGE; + break; + + default: + ASSERT (FALSE); + } + + GetHandleFormModuleGuid (ModuleGuid, &StartHandle); + Measurement->Handle = StartHandle; + break; + + case FPDT_GUID_QWORD_STRING_EVENT_TYPE: + ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid); + Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID); + if (IsStart) { + Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } else { + Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } + + // + // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE. + // + switch (Measurement->Identifier) { + case MODULE_DB_END_ID: + Measurement->Token = ALit_DB_START; + Measurement->Module = ALit_DB_START; + break; + default: + ASSERT (FALSE); + } + + GetHandleFormModuleGuid (ModuleGuid, &StartHandle); + Measurement->Handle = StartHandle; + break; + + case FPDT_DUAL_GUID_STRING_EVENT_TYPE: + ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1); + Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID); + if (IsStart) { + Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } else { + Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp; + } + + Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String; + Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String; + GetHandleFormModuleGuid (ModuleGuid, &StartHandle); + Measurement->Handle = StartHandle; + break; + + default: + break; + } +} + +/** + Search the start measurement in the mMeasurementList for the end measurement. + + @param EndMeasureMent Measurement for end record. + +**/ +VOID +SearchMeasurement ( + IN MEASUREMENT_RECORD *EndMeasureMent + ) +{ + INTN Index; + + for (Index = mMeasurementNum - 1; Index >= 0; Index--) { + if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) { + if ((mMeasurementList[Index].EndTimeStamp == 0) && (EndMeasureMent->Handle != NULL) && (mMeasurementList[Index].Handle != NULL) && + CompareGuid (mMeasurementList[Index].Handle, EndMeasureMent->Handle) && + (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) && + (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) + { + mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp; + break; + } + } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) { + if ((mMeasurementList[Index].EndTimeStamp == 0) && + (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) && + (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) && + (mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID)) + { + mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp; + break; + } + } else { + if ((mMeasurementList[Index].EndTimeStamp == 0) && (mMeasurementList[Index].Handle == EndMeasureMent->Handle) && + (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) && + (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) + { + mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp; + break; + } + } + } +} + +/** + Generate the measure record array. + +**/ +EFI_STATUS +BuildMeasurementList ( + ) +{ + EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader; + UINT8 *PerformanceTablePtr; + UINT8 *BasicBootTablePtr; + UINT64 ResetEnd; + UINT16 StartProgressId; + UINTN TableLength; + UINT8 *StartRecordEvent; + MEASUREMENT_RECORD MeasureMent; + + mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize); + if (mMeasurementList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Update the ResetEnd which was logged at the beginning of firmware image execution + // + TableLength = sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER); + BasicBootTablePtr = (mBootPerformanceTable + TableLength); + ResetEnd = ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)BasicBootTablePtr)->ResetEnd; + + if (ResetEnd > 0) { + mResetEnd = ResetEnd; + } + + TableLength = sizeof (BOOT_PERFORMANCE_TABLE); + PerformanceTablePtr = (mBootPerformanceTable + TableLength); + + while (TableLength < mBootPerformanceTableSize) { + RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)PerformanceTablePtr; + StartRecordEvent = (UINT8 *)RecordHeader; + StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID; + + // + // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0. + // If the record is the start record, fill the info to the measurement in the mMeasurementList. + // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp. + // + if (StartProgressId == 0) { + GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum])); + mMeasurementNum++; + } else if ((((StartProgressId >= PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x000F) == 0)) || + ((StartProgressId < PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x0001) != 0)))) + { + // + // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE + // So we need to identify these two kinds of record through different phase. + // + if (StartProgressId == PERF_CROSSMODULE_START_ID ) { + if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) { + mPeiPhase = TRUE; + } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) { + mDxePhase = TRUE; + mPeiPhase = FALSE; + } + } + + // Get measurement info form the start record to the mMeasurementList. + GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum])); + mMeasurementNum++; + } else { + ZeroMem (&MeasureMent, sizeof (MEASUREMENT_RECORD)); + GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent); + SearchMeasurement (&MeasureMent); + } + + TableLength += RecordHeader->Length; + PerformanceTablePtr += RecordHeader->Length; + } + + return EFI_SUCCESS; +} + +/** + Initialize the cumulative data. + +**/ +VOID +InitCumulativeData ( + VOID + ) +{ + UINTN Index; + + for (Index = 0; Index < NumCum; ++Index) { + CumData[Index].Count = 0; + CumData[Index].MinDur = PERF_MAXDUR; + CumData[Index].MaxDur = 0; + CumData[Index].Duration = 0; + } +} + +/** + Initialize the Summary data. + +**/ +VOID +InitSummaryData ( + VOID + ) +{ + SummaryData.NumTrace = 0; + SummaryData.NumIncomplete = 0; + SummaryData.NumSummary = 0; + SummaryData.NumHandles = 0; + SummaryData.NumPEIMs = 0; + SummaryData.NumGlobal = 0; +} + +/** + Dump performance data. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval SHELL_SUCCESS Command completed successfully. + @retval SHELL_INVALID_PARAMETER Command usage error. + @retval SHELL_ABORTED The user aborts the operation. + @retval value Unknown error. +**/ +SHELL_STATUS +RunDp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + LIST_ENTRY *ParamPackage; + CONST CHAR16 *CmdLineArg; + EFI_STATUS Status; + + PERFORMANCE_PROPERTY *PerformanceProperty; + UINTN Number2Display; + + EFI_STRING StringPtr; + BOOLEAN SummaryMode; + BOOLEAN VerboseMode; + BOOLEAN AllMode; + BOOLEAN RawMode; + BOOLEAN ExcludeMode; + BOOLEAN CumulativeMode; + CONST CHAR16 *CustomCumulativeToken; + PERF_CUM_DATA *CustomCumulativeData; + UINTN NameSize; + SHELL_STATUS ShellStatus; + TIMER_INFO TimerInfo; + UINT64 Intermediate; + + StringPtr = NULL; + SummaryMode = FALSE; + VerboseMode = FALSE; + AllMode = FALSE; + RawMode = FALSE; + ExcludeMode = FALSE; + CumulativeMode = FALSE; + CustomCumulativeData = NULL; + ShellStatus = SHELL_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize (); + ASSERT_EFI_ERROR (Status); + + // + // Process Command Line arguments + // + Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount (ParamPackage) > 1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } + + // + // Boolean options + // + VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v"); + SummaryMode = (BOOLEAN)(ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s")); + AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A"); + RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R"); + ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x"); + mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i"); + CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c"); + + if (AllMode && RawMode) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R"); + return SHELL_INVALID_PARAMETER; + } + + // Options with Values + if (ShellCommandLineGetFlag (ParamPackage, L"-n")) { + CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n"); + if (CmdLineArg == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } else { + if (!(RawMode || AllMode)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } + + Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n"); + return SHELL_INVALID_PARAMETER; + } else { + Number2Display = (UINTN)Intermediate; + if ((Number2Display == 0) || (Number2Display > MAXIMUM_DISPLAYCOUNT)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT); + return SHELL_INVALID_PARAMETER; + } + } + } + } else { + Number2Display = DEFAULT_DISPLAYCOUNT; + } + + if (ShellCommandLineGetFlag (ParamPackage, L"-t")) { + CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t"); + if (CmdLineArg == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } else { + Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t"); + return SHELL_INVALID_PARAMETER; + } else { + mInterestThreshold = Intermediate; + } + } + } else { + mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us + } + + if (ShellCommandLineGetFlag (ParamPackage, L"-c")) { + CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c"); + if (CustomCumulativeToken == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle); + return SHELL_INVALID_PARAMETER; + } else { + CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA)); + if (CustomCumulativeData == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Done; + } + + CustomCumulativeData->MinDur = PERF_MAXDUR; + CustomCumulativeData->MaxDur = 0; + CustomCumulativeData->Count = 0; + CustomCumulativeData->Duration = 0; + NameSize = StrLen (CustomCumulativeToken) + 1; + CustomCumulativeData->Name = AllocateZeroPool (NameSize); + if (CustomCumulativeData->Name == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Done; + } + + UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize); + } + } + + // + // DP dump performance data by parsing FPDT table in ACPI table. + // Folloing 3 steps are to get the measurement form the FPDT table. + // + + // + // 1. Get FPDT from ACPI table. + // + Status = GetBootPerformanceTable (); + if (EFI_ERROR (Status)) { + ShellStatus = Status; + goto Done; + } + + // + // 2. Cache the ModuleGuid and hanlde mapping table. + // + Status = BuildCachedGuidHandleTable (); + if (EFI_ERROR (Status)) { + ShellStatus = Status; + goto Done; + } + + // + // 3. Build the measurement array form the FPDT records. + // + Status = BuildMeasurementList (); + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Done; + } + + // + // Initialize the pre-defined cumulative data. + // + InitCumulativeData (); + + // + // Initialize the Summary data. + // + InitSummaryData (); + + // + // Timer specific processing + // + // Get the Performance counter characteristics: + // Freq = Frequency in Hz + // StartCount = Value loaded into the counter when it starts counting + // EndCount = Value counter counts to before it needs to be reset + // + Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty); + if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle); + goto Done; + } + + TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000); + TimerInfo.StartCount = 0; + TimerInfo.EndCount = 0xFFFF; + TimerInfo.CountUp = TRUE; + + // + // Print header + // + // print DP's build version + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION); + + // print performance timer characteristics + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency); + + if (VerboseMode && !RawMode) { + StringPtr = HiiGetString ( + mDpHiiHandle, + (EFI_STRING_ID)(TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), + NULL + ); + ASSERT (StringPtr != NULL); + // Print Timer count range and direction + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_TIMER_PROPERTIES), + mDpHiiHandle, + StringPtr, + TimerInfo.StartCount, + TimerInfo.EndCount + ); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold); + } + + /**************************************************************************** + **** Print Sections based on command line options + **** + **** Option modes have the following priority: + **** v Verbose -- Valid in combination with any other options + **** t Threshold -- Modifies All, Raw, and Cooked output + **** Default is 0 for All and Raw mode + **** Default is DEFAULT_THRESHOLD for "Cooked" mode + **** n Number2Display Used by All and Raw mode. Otherwise ignored. + **** A All -- R and S options are ignored + **** R Raw -- S option is ignored + **** s Summary -- Modifies "Cooked" output only + **** Cooked (Default) + ****************************************************************************/ + GatherStatistics (CustomCumulativeData); + if (CumulativeMode) { + ProcessCumulative (CustomCumulativeData); + } else if (AllMode) { + Status = DumpAllTrace (Number2Display, ExcludeMode); + if (Status == EFI_ABORTED) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + } else if (RawMode) { + Status = DumpRawTrace (Number2Display, ExcludeMode); + if (Status == EFI_ABORTED) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + } else { + // ------------- Begin Cooked Mode Processing + ProcessPhases (); + if ( !SummaryMode) { + Status = ProcessHandles (ExcludeMode); + if (Status == EFI_ABORTED) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + + Status = ProcessPeims (); + if (Status == EFI_ABORTED) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + + Status = ProcessGlobal (); + if (Status == EFI_ABORTED) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + + ProcessCumulative (NULL); + } + } // ------------- End of Cooked Mode Processing + + if ( VerboseMode || SummaryMode) { + DumpStatistics (); + } + +Done: + if (ParamPackage != NULL) { + ShellCommandLineFreeVarList (ParamPackage); + } + + SHELL_FREE_NON_NULL (StringPtr); + if (CustomCumulativeData != NULL) { + SHELL_FREE_NON_NULL (CustomCumulativeData->Name); + } + + SHELL_FREE_NON_NULL (CustomCumulativeData); + + SHELL_FREE_NON_NULL (mMeasurementList); + + SHELL_FREE_NON_NULL (mCacheHandleGuidTable); + + mMeasurementNum = 0; + mCachePairCount = 0; + return ShellStatus; +} + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param ImageHandle The image handle of the process. + + @return HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + EFI_HII_HANDLE HiiHandle; + + // + // Retrieve HII package list from ImageHandle + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **)&PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + // + // Publish HII package list to HII Database. + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &HiiHandle + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + return HiiHandle; +} diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h index ee09ca4913..b8fd73f2dc 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h @@ -1,140 +1,140 @@ -/** @file
- Header file for 'dp' command functions.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _DP_H_
-#define _DP_H_
-
-#include <Uefi.h>
-
-#include <Guid/Performance.h>
-#include <Guid/ExtendedFirmwarePerformance.h>
-#include <Guid/FirmwarePerformance.h>
-
-#include <Protocol/HiiPackageList.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/UnicodeCollation.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PcdLib.h>
-#include <Library/SortLib.h>
-#include <Library/HiiLib.h>
-#include <Library/FileHandleLib.h>
-#include <Library/UefiHiiServicesLib.h>
-#include <Library/PerformanceLib.h>
-
-extern EFI_HII_HANDLE mDpHiiHandle;
-
-#define DP_MAJOR_VERSION 2
-#define DP_MINOR_VERSION 5
-
-/**
- * The value assigned to DP_DEBUG controls which debug output
- * is generated. Set it to ZERO to disable.
-**/
-#define DP_DEBUG 0
-
-#define DEFAULT_THRESHOLD 1000 ///< One millisecond.
-#define DEFAULT_DISPLAYCOUNT 50
-#define MAXIMUM_DISPLAYCOUNT 999999 ///< Arbitrary maximum reasonable number.
-
-#define PERF_MAXDUR 0xFFFFFFFFFFFFFFFFULL
-
-/// Determine whether 0 <= C < L. If L == 0, return true regardless of C.
-#define WITHIN_LIMIT(C, L) ( ((L) == 0) || ((C) < (L)) )
-
-/// Structure for storing Timer specific information.
-typedef struct {
- UINT64 StartCount; ///< Value timer is initialized with.
- UINT64 EndCount; ///< Value timer has just before it wraps.
- UINT32 Frequency; ///< Timer count frequency in KHz.
- BOOLEAN CountUp; ///< TRUE if the counter counts up.
-} TIMER_INFO;
-
-/** Initialize one PERF_CUM_DATA structure instance for token t.
- *
- * This parameterized macro takes a single argument, t, which is expected
- * to resolve to a pointer to an ASCII string literal. This parameter may
- * take any one of the following forms:
- * - PERF_INIT_CUM_DATA("Token") A string literal
- * - PERF_INIT_CUM_DATA(pointer) A pointer -- CHAR8 *pointer;
- * - PERF_INIT_CUM_DATA(array) Address of an array -- CHAR8 array[N];
-**/
-#define PERF_INIT_CUM_DATA(t) { 0ULL, PERF_MAXDUR, 0ULL, (t), 0U }
-
-typedef struct {
- UINT64 Duration; ///< Cumulative duration for this item.
- UINT64 MinDur; ///< Smallest duration encountered.
- UINT64 MaxDur; ///< Largest duration encountered.
- CHAR8 *Name; ///< ASCII name of this item.
- UINT32 Count; ///< Total number of measurements accumulated.
-} PERF_CUM_DATA;
-
-typedef struct {
- UINT32 NumTrace; ///< Number of recorded TRACE performance measurements.
- UINT32 NumIncomplete; ///< Number of measurements with no END value.
- UINT32 NumSummary; ///< Number of summary section measurements.
- UINT32 NumHandles; ///< Number of measurements with handles.
- UINT32 NumPEIMs; ///< Number of measurements of PEIMs.
- UINT32 NumGlobal; ///< Number of measurements with END value and NULL handle.
-} PERF_SUMMARY_DATA;
-
-typedef struct {
- CONST VOID *Handle;
- CONST CHAR8 *Token; ///< Measured token string name.
- CONST CHAR8 *Module; ///< Module string name.
- UINT64 StartTimeStamp; ///< Start time point.
- UINT64 EndTimeStamp; ///< End time point.
- UINT32 Identifier; ///< Identifier.
-} MEASUREMENT_RECORD;
-
-typedef struct {
- CHAR8 *Name; ///< Measured token string name.
- UINT64 CumulativeTime; ///< Accumulated Elapsed Time.
- UINT64 MinTime; ///< Minimum Elapsed Time.
- UINT64 MaxTime; ///< Maximum Elapsed Time.
- UINT32 Count; ///< Number of measurements accumulated.
-} PROFILE_RECORD;
-
-/**
- Dump performance data.
-
- @param[in] ImageHandle The image handle.
- @param[in] SystemTable The system table.
-
- @retval SHELL_SUCCESS Command completed successfully.
- @retval SHELL_INVALID_PARAMETER Command usage error.
- @retval SHELL_ABORTED The user aborts the operation.
- @retval value Unknown error.
-**/
-SHELL_STATUS
-RunDp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param ImageHandle The image handle of the process.
-
- @return HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- EFI_HANDLE ImageHandle
- );
-
-#endif // _DP_H_
+/** @file + Header file for 'dp' command functions. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _DP_H_ +#define _DP_H_ + +#include <Uefi.h> + +#include <Guid/Performance.h> +#include <Guid/ExtendedFirmwarePerformance.h> +#include <Guid/FirmwarePerformance.h> + +#include <Protocol/HiiPackageList.h> +#include <Protocol/DevicePath.h> +#include <Protocol/LoadedImage.h> +#include <Protocol/UnicodeCollation.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/PcdLib.h> +#include <Library/SortLib.h> +#include <Library/HiiLib.h> +#include <Library/FileHandleLib.h> +#include <Library/UefiHiiServicesLib.h> +#include <Library/PerformanceLib.h> + +extern EFI_HII_HANDLE mDpHiiHandle; + +#define DP_MAJOR_VERSION 2 +#define DP_MINOR_VERSION 5 + +/** + * The value assigned to DP_DEBUG controls which debug output + * is generated. Set it to ZERO to disable. +**/ +#define DP_DEBUG 0 + +#define DEFAULT_THRESHOLD 1000 ///< One millisecond. +#define DEFAULT_DISPLAYCOUNT 50 +#define MAXIMUM_DISPLAYCOUNT 999999 ///< Arbitrary maximum reasonable number. + +#define PERF_MAXDUR 0xFFFFFFFFFFFFFFFFULL + +/// Determine whether 0 <= C < L. If L == 0, return true regardless of C. +#define WITHIN_LIMIT(C, L) ( ((L) == 0) || ((C) < (L)) ) + +/// Structure for storing Timer specific information. +typedef struct { + UINT64 StartCount; ///< Value timer is initialized with. + UINT64 EndCount; ///< Value timer has just before it wraps. + UINT32 Frequency; ///< Timer count frequency in KHz. + BOOLEAN CountUp; ///< TRUE if the counter counts up. +} TIMER_INFO; + +/** Initialize one PERF_CUM_DATA structure instance for token t. + * + * This parameterized macro takes a single argument, t, which is expected + * to resolve to a pointer to an ASCII string literal. This parameter may + * take any one of the following forms: + * - PERF_INIT_CUM_DATA("Token") A string literal + * - PERF_INIT_CUM_DATA(pointer) A pointer -- CHAR8 *pointer; + * - PERF_INIT_CUM_DATA(array) Address of an array -- CHAR8 array[N]; +**/ +#define PERF_INIT_CUM_DATA(t) { 0ULL, PERF_MAXDUR, 0ULL, (t), 0U } + +typedef struct { + UINT64 Duration; ///< Cumulative duration for this item. + UINT64 MinDur; ///< Smallest duration encountered. + UINT64 MaxDur; ///< Largest duration encountered. + CHAR8 *Name; ///< ASCII name of this item. + UINT32 Count; ///< Total number of measurements accumulated. +} PERF_CUM_DATA; + +typedef struct { + UINT32 NumTrace; ///< Number of recorded TRACE performance measurements. + UINT32 NumIncomplete; ///< Number of measurements with no END value. + UINT32 NumSummary; ///< Number of summary section measurements. + UINT32 NumHandles; ///< Number of measurements with handles. + UINT32 NumPEIMs; ///< Number of measurements of PEIMs. + UINT32 NumGlobal; ///< Number of measurements with END value and NULL handle. +} PERF_SUMMARY_DATA; + +typedef struct { + CONST VOID *Handle; + CONST CHAR8 *Token; ///< Measured token string name. + CONST CHAR8 *Module; ///< Module string name. + UINT64 StartTimeStamp; ///< Start time point. + UINT64 EndTimeStamp; ///< End time point. + UINT32 Identifier; ///< Identifier. +} MEASUREMENT_RECORD; + +typedef struct { + CHAR8 *Name; ///< Measured token string name. + UINT64 CumulativeTime; ///< Accumulated Elapsed Time. + UINT64 MinTime; ///< Minimum Elapsed Time. + UINT64 MaxTime; ///< Maximum Elapsed Time. + UINT32 Count; ///< Number of measurements accumulated. +} PROFILE_RECORD; + +/** + Dump performance data. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval SHELL_SUCCESS Command completed successfully. + @retval SHELL_INVALID_PARAMETER Command usage error. + @retval SHELL_ABORTED The user aborts the operation. + @retval value Unknown error. +**/ +SHELL_STATUS +RunDp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param ImageHandle The image handle of the process. + + @return HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + EFI_HANDLE ImageHandle + ); + +#endif // _DP_H_ diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.uni b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.uni index ef2e7708b8..a9379a8d09 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.uni +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.uni @@ -1,129 +1,129 @@ -// *++
-//
-// (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
-// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
-// (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-//
-// Module Name:
-//
-// DpStrings.uni
-//
-// Abstract:
-//
-// String definitions for the Shell dp command
-//
-// Revision History:
-//
-// --*/
-
-/=#
-
-#langdef en-US "English"
-
-#string STR_DP_UP #language en-US "UP"
-#string STR_DP_DOWN #language en-US "DOWN"
-#string STR_DP_DASHES #language en-US "-------------------------------------------------------------------------------\n"
-#string STR_DP_SECTION_HEADER #language en-US "\n==[ %s ]========\n"
-#string STR_DP_INVALID_ARG #language en-US "Invalid argument(s)\n"
-#string STR_DP_TOO_MANY #language en-US "Too many arguments\n"
-#string STR_DP_TOO_FEW #language en-US "Too few arguments\n"
-#string STR_DP_INVALID_NUM_ARG #language en-US "Invalid argument(s), the value of %H%s%N must be numbers\n"
-#string STR_DP_INVALID_RANGE #language en-US "Invalid argument(s), the value of %H%s%N must be between %H%d%N and %H%d%N\n"
-#string STR_DP_CONFLICT_ARG #language en-US "Invalid argument(s), %H%s%N can not be used together with %H%s%N\n"
-#string STR_DP_NO_RAW_ALL #language en-US "Invalid argument(s), -n flag must use with -A or -R\n"
-#string STR_DP_HANDLES_ERROR #language en-US "Locate all handles error - %r\n"
-#string STR_DP_ERROR_NAME #language en-US "Unknown driver name"
-#string STR_PERF_PROPERTY_NOT_FOUND #language en-US "Performance property not found\n"
-#string STR_DP_BUILD_REVISION #language en-US "\nDP Build Version: %d.%d\n"
-#string STR_DP_KHZ #language en-US "System Performance Timer Frequency: %,8d (KHz)\n"
-#string STR_DP_TIMER_PROPERTIES #language en-US "System Performance Timer counts %s from 0x%Lx to 0x%Lx\n"
-#string STR_DP_VERBOSE_THRESHOLD #language en-US "Measurements less than %,Ld microseconds are not displayed.\n"
-#string STR_DP_SECTION_PHASES #language en-US "Major Phases"
-#string STR_DP_RESET_END #language en-US " Reset End: %L8d (us)\n"
-#string STR_DP_SEC_PHASE #language en-US " SEC Phase Duration: %L8d (us)\n"
-#string STR_DP_PHASE_BDSTO #language en-US " BDS Timeout: %L8d (ms) included in BDS Duration\n"
-#string STR_DP_PHASE_DURATION #language en-US "%5a Phase Duration: %L8d (ms)\n"
-#string STR_DP_TOTAL_DURATION #language en-US "Total Duration: %L8d (ms)\n"
-#string STR_DP_SECTION_DRIVERS #language en-US "Drivers by Handle"
-#string STR_DP_HANDLE_SECTION #language en-US "Index: Handle Driver Name Description Time(us)\n"
-#string STR_DP_HANDLE_VARS #language en-US "%5d: [%3x] %36s %11s %L8d\n"
-#string STR_DP_HANDLE_SECTION2 #language en-US "Index: Handle Driver Name Description Time(us) ID\n"
-#string STR_DP_HANDLE_VARS2 #language en-US "%5d: [%3x] %36s %11s %L8d %5d\n"
-#string STR_DP_SECTION_PEIMS #language en-US "PEIMs"
-#string STR_DP_PEIM_SECTION #language en-US "Index: Instance GUID Token Time(us)\n"
-#string STR_DP_PEIM_VARS #language en-US "%5d: %g PEIM %L8d\n"
-#string STR_DP_PEIM_SECTION2 #language en-US "Index: Instance GUID Token Time(us) ID\n"
-#string STR_DP_PEIM_VARS2 #language en-US "%5d: %g PEIM %L8d %5d\n"
-#string STR_DP_SECTION_GENERAL #language en-US "General"
-#string STR_DP_GLOBAL_SECTION #language en-US "Index Name Description Time(us)\n"
-#string STR_DP_GLOBAL_VARS #language en-US "%5d:%25s %31s %L8d\n"
-#string STR_DP_GLOBAL_SECTION2 #language en-US "Index Name Description Time(us) ID\n"
-#string STR_DP_GLOBAL_VARS2 #language en-US "%5d:%25s %31s %L8d %5d\n"
-#string STR_DP_SECTION_CUMULATIVE #language en-US "Cumulative"
-#string STR_DP_CUMULATIVE_SECT_1 #language en-US "(Times in microsec.) Cumulative Average Shortest Longest\n"
-#string STR_DP_CUMULATIVE_SECT_2 #language en-US " Name Count Duration Duration Duration Duration\n"
-#string STR_DP_CUMULATIVE_STATS #language en-US "%11a %8d %L10d %L10d %L10d %L10d\n"
-#string STR_DP_SECTION_STATISTICS #language en-US "Statistics"
-#string STR_DP_STATS_NUMTRACE #language en-US "There were %d measurements taken, of which:\n"
-#string STR_DP_STATS_NUMINCOMPLETE #language en-US "%,8d are incomplete.\n"
-#string STR_DP_STATS_NUMPHASES #language en-US "%,8d are major execution phases.\n"
-#string STR_DP_STATS_NUMHANDLES #language en-US "%,8d have non-NULL handles, %d are NULL.\n"
-#string STR_DP_STATS_NUMPEIMS #language en-US "%,8d are PEIMs.\n"
-#string STR_DP_STATS_NUMGLOBALS #language en-US "%,8d are general measurements.\n"
-#string STR_DP_STATS_NUMPROFILE #language en-US "%,8d are profiling records.\n"
-#string STR_DP_SECTION_ALL #language en-US "Sequential Trace Records"
-#string STR_DP_ALL_HEADR #language en-US "\nIndex Handle Module Token Time(us)\n"
-#string STR_DP_ALL_VARS #language en-US "%5d:%3s0x%08p %36s %13s %L8d\n"
-#string STR_DP_ALL_DASHES2 #language en-US "-------------------------------------------------------------------------------------\n"
-#string STR_DP_ALL_HEADR2 #language en-US "\nIndex Handle Module Token Time(us) ID\n"
-#string STR_DP_ALL_VARS2 #language en-US "%5d:%3s0x%08p %36s %13s %L8d %5d\n"
-#string STR_DP_SECTION_RAWTRACE #language en-US "RAW Trace"
-#string STR_DP_RAW_DASHES #language en-US "---------------------------------------------------------------------------------------------------------------------------\n"
-#string STR_DP_RAW_VARS #language en-US "%5d: %16LX %16LX %16LX %31a %31a\n"
-#string STR_DP_RAW_HEADR #language en-US "\nIndex Handle Start Count End Count Token Module\n"
-#string STR_DP_RAW_DASHES2 #language en-US "---------------------------------------------------------------------------------------------------------------------------------\n"
-#string STR_DP_RAW_VARS2 #language en-US "%5d: %16LX %16LX %16LX %31a %31a %5d\n"
-#string STR_DP_RAW_HEADR2 #language en-US "\nIndex Handle Start Count End Count Token Module ID\n"
-#string STR_DP_INCOMPLETE #language en-US " I "
-#string STR_DP_COMPLETE #language en-US " "
-#string STR_ALIT_UNKNOWN #language en-US "Unknown"
-#string STR_DP_GET_ACPI_FPDT_FAIL #language en-US "Fail to get Firmware Performance Data Table (FPDT) in ACPI Table\n"
-
-#string STR_GET_HELP_DP #language en-US ""
-".TH dp 0 "Display performance metrics"\r\n"
-".SH NAME\r\n"
-"Displays performance metrics that are stored in memory.\r\n"
-".SH SYNOPSIS\r\n"
-"DP [-b] [-v] [-x] [-s | -A | -R] [-t value] [-n count] [-c [token]][-i] [-?]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -b - Displays on multiple pages\r\n"
-" -v - Displays additional information\r\n"
-" -x - Prevents display of individual measurements for cumulative items\r\n"
-" -s - Displays summary information only\r\n"
-" -A - Displays all measurements in a list\r\n"
-" -R - Displays all measurements in raw format\r\n"
-" -t VALUE - Sets display threshold to VALUE microseconds\r\n"
-" -n COUNT - Limits display to COUNT lines in All and Raw modes\r\n"
-" -i - Displays identifier\r\n"
-" -c TOKEN - Display pre-defined and custom cumulative data\r\n"
-" Pre-defined cumulative token are:\r\n"
-" 1. LoadImage:\r\n"
-" 2. StartImage:\r\n"
-" 3. DB:Start:\r\n"
-" 4. DB:Support:\r\n"
-" -? - Displays DP help information\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. Displays Performance metrics that are stored in memory.\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_NOT_FOUND The requested option was not found.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed in parameters was incorrectly formatted or its value was out of bounds.\r\n"
-" SHELL_UNSUPPORTED The action as requested was unsupported.\r\n"
-" SHELL_OUT_OF_RESOURCES There was insufficient free space for the request to be completed.\r\n"
+// *++ +// +// (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR> +// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +// (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// +// Module Name: +// +// DpStrings.uni +// +// Abstract: +// +// String definitions for the Shell dp command +// +// Revision History: +// +// --*/ + +/=# + +#langdef en-US "English" + +#string STR_DP_UP #language en-US "UP" +#string STR_DP_DOWN #language en-US "DOWN" +#string STR_DP_DASHES #language en-US "-------------------------------------------------------------------------------\n" +#string STR_DP_SECTION_HEADER #language en-US "\n==[ %s ]========\n" +#string STR_DP_INVALID_ARG #language en-US "Invalid argument(s)\n" +#string STR_DP_TOO_MANY #language en-US "Too many arguments\n" +#string STR_DP_TOO_FEW #language en-US "Too few arguments\n" +#string STR_DP_INVALID_NUM_ARG #language en-US "Invalid argument(s), the value of %H%s%N must be numbers\n" +#string STR_DP_INVALID_RANGE #language en-US "Invalid argument(s), the value of %H%s%N must be between %H%d%N and %H%d%N\n" +#string STR_DP_CONFLICT_ARG #language en-US "Invalid argument(s), %H%s%N can not be used together with %H%s%N\n" +#string STR_DP_NO_RAW_ALL #language en-US "Invalid argument(s), -n flag must use with -A or -R\n" +#string STR_DP_HANDLES_ERROR #language en-US "Locate all handles error - %r\n" +#string STR_DP_ERROR_NAME #language en-US "Unknown driver name" +#string STR_PERF_PROPERTY_NOT_FOUND #language en-US "Performance property not found\n" +#string STR_DP_BUILD_REVISION #language en-US "\nDP Build Version: %d.%d\n" +#string STR_DP_KHZ #language en-US "System Performance Timer Frequency: %,8d (KHz)\n" +#string STR_DP_TIMER_PROPERTIES #language en-US "System Performance Timer counts %s from 0x%Lx to 0x%Lx\n" +#string STR_DP_VERBOSE_THRESHOLD #language en-US "Measurements less than %,Ld microseconds are not displayed.\n" +#string STR_DP_SECTION_PHASES #language en-US "Major Phases" +#string STR_DP_RESET_END #language en-US " Reset End: %L8d (us)\n" +#string STR_DP_SEC_PHASE #language en-US " SEC Phase Duration: %L8d (us)\n" +#string STR_DP_PHASE_BDSTO #language en-US " BDS Timeout: %L8d (ms) included in BDS Duration\n" +#string STR_DP_PHASE_DURATION #language en-US "%5a Phase Duration: %L8d (ms)\n" +#string STR_DP_TOTAL_DURATION #language en-US "Total Duration: %L8d (ms)\n" +#string STR_DP_SECTION_DRIVERS #language en-US "Drivers by Handle" +#string STR_DP_HANDLE_SECTION #language en-US "Index: Handle Driver Name Description Time(us)\n" +#string STR_DP_HANDLE_VARS #language en-US "%5d: [%3x] %36s %11s %L8d\n" +#string STR_DP_HANDLE_SECTION2 #language en-US "Index: Handle Driver Name Description Time(us) ID\n" +#string STR_DP_HANDLE_VARS2 #language en-US "%5d: [%3x] %36s %11s %L8d %5d\n" +#string STR_DP_SECTION_PEIMS #language en-US "PEIMs" +#string STR_DP_PEIM_SECTION #language en-US "Index: Instance GUID Token Time(us)\n" +#string STR_DP_PEIM_VARS #language en-US "%5d: %g PEIM %L8d\n" +#string STR_DP_PEIM_SECTION2 #language en-US "Index: Instance GUID Token Time(us) ID\n" +#string STR_DP_PEIM_VARS2 #language en-US "%5d: %g PEIM %L8d %5d\n" +#string STR_DP_SECTION_GENERAL #language en-US "General" +#string STR_DP_GLOBAL_SECTION #language en-US "Index Name Description Time(us)\n" +#string STR_DP_GLOBAL_VARS #language en-US "%5d:%25s %31s %L8d\n" +#string STR_DP_GLOBAL_SECTION2 #language en-US "Index Name Description Time(us) ID\n" +#string STR_DP_GLOBAL_VARS2 #language en-US "%5d:%25s %31s %L8d %5d\n" +#string STR_DP_SECTION_CUMULATIVE #language en-US "Cumulative" +#string STR_DP_CUMULATIVE_SECT_1 #language en-US "(Times in microsec.) Cumulative Average Shortest Longest\n" +#string STR_DP_CUMULATIVE_SECT_2 #language en-US " Name Count Duration Duration Duration Duration\n" +#string STR_DP_CUMULATIVE_STATS #language en-US "%11a %8d %L10d %L10d %L10d %L10d\n" +#string STR_DP_SECTION_STATISTICS #language en-US "Statistics" +#string STR_DP_STATS_NUMTRACE #language en-US "There were %d measurements taken, of which:\n" +#string STR_DP_STATS_NUMINCOMPLETE #language en-US "%,8d are incomplete.\n" +#string STR_DP_STATS_NUMPHASES #language en-US "%,8d are major execution phases.\n" +#string STR_DP_STATS_NUMHANDLES #language en-US "%,8d have non-NULL handles, %d are NULL.\n" +#string STR_DP_STATS_NUMPEIMS #language en-US "%,8d are PEIMs.\n" +#string STR_DP_STATS_NUMGLOBALS #language en-US "%,8d are general measurements.\n" +#string STR_DP_STATS_NUMPROFILE #language en-US "%,8d are profiling records.\n" +#string STR_DP_SECTION_ALL #language en-US "Sequential Trace Records" +#string STR_DP_ALL_HEADR #language en-US "\nIndex Handle Module Token Time(us)\n" +#string STR_DP_ALL_VARS #language en-US "%5d:%3s0x%08p %36s %13s %L8d\n" +#string STR_DP_ALL_DASHES2 #language en-US "-------------------------------------------------------------------------------------\n" +#string STR_DP_ALL_HEADR2 #language en-US "\nIndex Handle Module Token Time(us) ID\n" +#string STR_DP_ALL_VARS2 #language en-US "%5d:%3s0x%08p %36s %13s %L8d %5d\n" +#string STR_DP_SECTION_RAWTRACE #language en-US "RAW Trace" +#string STR_DP_RAW_DASHES #language en-US "---------------------------------------------------------------------------------------------------------------------------\n" +#string STR_DP_RAW_VARS #language en-US "%5d: %16LX %16LX %16LX %31a %31a\n" +#string STR_DP_RAW_HEADR #language en-US "\nIndex Handle Start Count End Count Token Module\n" +#string STR_DP_RAW_DASHES2 #language en-US "---------------------------------------------------------------------------------------------------------------------------------\n" +#string STR_DP_RAW_VARS2 #language en-US "%5d: %16LX %16LX %16LX %31a %31a %5d\n" +#string STR_DP_RAW_HEADR2 #language en-US "\nIndex Handle Start Count End Count Token Module ID\n" +#string STR_DP_INCOMPLETE #language en-US " I " +#string STR_DP_COMPLETE #language en-US " " +#string STR_ALIT_UNKNOWN #language en-US "Unknown" +#string STR_DP_GET_ACPI_FPDT_FAIL #language en-US "Fail to get Firmware Performance Data Table (FPDT) in ACPI Table\n" + +#string STR_GET_HELP_DP #language en-US "" +".TH dp 0 "Display performance metrics"\r\n" +".SH NAME\r\n" +"Displays performance metrics that are stored in memory.\r\n" +".SH SYNOPSIS\r\n" +"DP [-b] [-v] [-x] [-s | -A | -R] [-t value] [-n count] [-c [token]][-i] [-?]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -b - Displays on multiple pages\r\n" +" -v - Displays additional information\r\n" +" -x - Prevents display of individual measurements for cumulative items\r\n" +" -s - Displays summary information only\r\n" +" -A - Displays all measurements in a list\r\n" +" -R - Displays all measurements in raw format\r\n" +" -t VALUE - Sets display threshold to VALUE microseconds\r\n" +" -n COUNT - Limits display to COUNT lines in All and Raw modes\r\n" +" -i - Displays identifier\r\n" +" -c TOKEN - Display pre-defined and custom cumulative data\r\n" +" Pre-defined cumulative token are:\r\n" +" 1. LoadImage:\r\n" +" 2. StartImage:\r\n" +" 3. DB:Start:\r\n" +" 4. DB:Support:\r\n" +" -? - Displays DP help information\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. Displays Performance metrics that are stored in memory.\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_NOT_FOUND The requested option was not found.\r\n" +" SHELL_INVALID_PARAMETER One of the passed in parameters was incorrectly formatted or its value was out of bounds.\r\n" +" SHELL_UNSUPPORTED The action as requested was unsupported.\r\n" +" SHELL_OUT_OF_RESOURCES There was insufficient free space for the request to be completed.\r\n" diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.c index f148583493..6440f8c1b7 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.c @@ -1,48 +1,48 @@ -/** @file
- Entrypoint of "dp" shell standalone application.
-
- Copyright (c) 2017, Intel Corporation. All rights reserved. <BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "Dp.h"
-
-//
-// String token ID of help message text.
-// Shell supports to find help message in the resource section of an application image if
-// .MAN file is not found. This global variable is added to make build tool recognizes
-// that the help string is consumed by user and then build tool will add the string into
-// the resource section. Thus the application can use '-?' option to show help message in
-// Shell.
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_DP);
-
-/**
- Entry point of Tftp standalone application.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Tftp command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing tftp command.
-**/
-EFI_STATUS
-EFIAPI
-DpAppInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mDpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mDpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = (EFI_STATUS)RunDp (ImageHandle, SystemTable);
- HiiRemovePackages (mDpHiiHandle);
- return Status;
-}
+/** @file + Entrypoint of "dp" shell standalone application. + + Copyright (c) 2017, Intel Corporation. All rights reserved. <BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "Dp.h" + +// +// String token ID of help message text. +// Shell supports to find help message in the resource section of an application image if +// .MAN file is not found. This global variable is added to make build tool recognizes +// that the help string is consumed by user and then build tool will add the string into +// the resource section. Thus the application can use '-?' option to show help message in +// Shell. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_DP); + +/** + Entry point of Tftp standalone application. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Tftp command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing tftp command. +**/ +EFI_STATUS +EFIAPI +DpAppInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mDpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mDpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = (EFI_STATUS)RunDp (ImageHandle, SystemTable); + HiiRemovePackages (mDpHiiHandle); + return Status; +} diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf index d9e1c23a1e..8abc638c8d 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf @@ -1,65 +1,65 @@ -## @file
-# Provides Shell 'dp' standalone application.
-#
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = dp
- FILE_GUID = 1831A379-2D48-45BD-9744-D4059D93815D
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- ENTRY_POINT = DpAppInitialize
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Dp.uni
- Dp.c
- Dp.h
- Literals.h
- Literals.c
- DpInternal.h
- DpUtilities.c
- DpTrace.c
- DpApp.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- UefiApplicationEntryPoint
- SortLib
- PrintLib
- DevicePathLib
- PerformanceLib
- DxeServicesLib
- PeCoffGetEntryPointLib
-
-[Guids]
- gPerformanceProtocolGuid ## CONSUMES ## SystemTable
- gEdkiiFpdtExtendedFirmwarePerformanceGuid ## CONSUMES ## SystemTable
-
-[Protocols]
- gEfiLoadedImageProtocolGuid ## CONSUMES
- gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES
- gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
-
+## @file +# Provides Shell 'dp' standalone application. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = dp + FILE_GUID = 1831A379-2D48-45BD-9744-D4059D93815D + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = DpAppInitialize +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Dp.uni + Dp.c + Dp.h + Literals.h + Literals.c + DpInternal.h + DpUtilities.c + DpTrace.c + DpApp.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + UefiApplicationEntryPoint + SortLib + PrintLib + DevicePathLib + PerformanceLib + DxeServicesLib + PeCoffGetEntryPointLib + +[Guids] + gPerformanceProtocolGuid ## CONSUMES ## SystemTable + gEdkiiFpdtExtendedFirmwarePerformanceGuid ## CONSUMES ## SystemTable + +[Protocols] + gEfiLoadedImageProtocolGuid ## CONSUMES + gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES + gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.c index e4ee4cc5ec..130b537025 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.c @@ -1,128 +1,128 @@ -/** @file
- Produce "dp" shell dynamic command.
-
- Copyright (c) 2017, Intel Corporation. All rights reserved. <BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "Dp.h"
-#include <Protocol/ShellDynamicCommand.h>
-
-/**
- This is the shell command handler function pointer callback type. This
- function handles the command when it is invoked in the shell.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] SystemTable The pointer to the system table.
- @param[in] ShellParameters The parameters associated with the command.
- @param[in] Shell The instance of the shell protocol used in the context
- of processing this command.
-
- @return EFI_SUCCESS the operation was successful
- @return other the operation failed.
-**/
-SHELL_STATUS
-EFIAPI
-DpCommandHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- )
-{
- gEfiShellParametersProtocol = ShellParameters;
- gEfiShellProtocol = Shell;
- return RunDp (gImageHandle, SystemTable);
-}
-
-/**
- This is the command help handler function pointer callback type. This
- function is responsible for displaying help information for the associated
- command.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] Language The pointer to the language string to use.
-
- @return string Pool allocated help string, must be freed by caller
-**/
-CHAR16 *
-EFIAPI
-DpCommandGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- )
-{
- return HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_GET_HELP_DP), Language);
-}
-
-EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mDpDynamicCommand = {
- L"dp",
- DpCommandHandler,
- DpCommandGetHelp
-};
-
-/**
- Entry point of Tftp Dynamic Command.
-
- Produce the DynamicCommand protocol to handle "tftp" command.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Tftp command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing tftp command.
-**/
-EFI_STATUS
-EFIAPI
-DpCommandInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mDpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mDpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mDpDynamicCommand
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
-/**
- Tftp driver unload handler.
-
- @param ImageHandle The image handle of the process.
-
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
-**/
-EFI_STATUS
-EFIAPI
-DpUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- Status = gBS->UninstallProtocolInterface (
- ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- &mDpDynamicCommand
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HiiRemovePackages (mDpHiiHandle);
- return EFI_SUCCESS;
-}
+/** @file + Produce "dp" shell dynamic command. + + Copyright (c) 2017, Intel Corporation. All rights reserved. <BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "Dp.h" +#include <Protocol/ShellDynamicCommand.h> + +/** + This is the shell command handler function pointer callback type. This + function handles the command when it is invoked in the shell. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] SystemTable The pointer to the system table. + @param[in] ShellParameters The parameters associated with the command. + @param[in] Shell The instance of the shell protocol used in the context + of processing this command. + + @return EFI_SUCCESS the operation was successful + @return other the operation failed. +**/ +SHELL_STATUS +EFIAPI +DpCommandHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + gEfiShellParametersProtocol = ShellParameters; + gEfiShellProtocol = Shell; + return RunDp (gImageHandle, SystemTable); +} + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed by caller +**/ +CHAR16 * +EFIAPI +DpCommandGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + return HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_GET_HELP_DP), Language); +} + +EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mDpDynamicCommand = { + L"dp", + DpCommandHandler, + DpCommandGetHelp +}; + +/** + Entry point of Tftp Dynamic Command. + + Produce the DynamicCommand protocol to handle "tftp" command. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Tftp command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing tftp command. +**/ +EFI_STATUS +EFIAPI +DpCommandInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mDpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mDpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + EFI_NATIVE_INTERFACE, + &mDpDynamicCommand + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Tftp driver unload handler. + + @param ImageHandle The image handle of the process. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. +**/ +EFI_STATUS +EFIAPI +DpUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status = gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mDpDynamicCommand + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiRemovePackages (mDpHiiHandle); + return EFI_SUCCESS; +} diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf index 2723fee706..17b66fe9dd 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf @@ -1,69 +1,69 @@ -## @file
-# Provides Shell 'dp' dynamic command.
-#
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = dpDynamicCommand
- FILE_GUID = 0253F9FA-129A-4A8D-B12E-7DC2B6376302
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = DpCommandInitialize
- UNLOAD_IMAGE = DpUnload
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Dp.uni
- Dp.c
- Dp.h
- Literals.h
- Literals.c
- DpInternal.h
- DpUtilities.c
- DpTrace.c
- DpDynamicCommand.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- SortLib
- PrintLib
- DevicePathLib
- PerformanceLib
- DxeServicesLib
- PeCoffGetEntryPointLib
-
-[Guids]
- gPerformanceProtocolGuid ## CONSUMES ## SystemTable
- gEdkiiFpdtExtendedFirmwarePerformanceGuid ## CONSUMES ## SystemTable
-
-[Protocols]
- gEfiLoadedImageProtocolGuid ## CONSUMES
- gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES
- gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
- gEfiShellDynamicCommandProtocolGuid ## PRODUCES
-
-[DEPEX]
- TRUE
+## @file +# Provides Shell 'dp' dynamic command. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = dpDynamicCommand + FILE_GUID = 0253F9FA-129A-4A8D-B12E-7DC2B6376302 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = DpCommandInitialize + UNLOAD_IMAGE = DpUnload +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Dp.uni + Dp.c + Dp.h + Literals.h + Literals.c + DpInternal.h + DpUtilities.c + DpTrace.c + DpDynamicCommand.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + UefiDriverEntryPoint + SortLib + PrintLib + DevicePathLib + PerformanceLib + DxeServicesLib + PeCoffGetEntryPointLib + +[Guids] + gPerformanceProtocolGuid ## CONSUMES ## SystemTable + gEdkiiFpdtExtendedFirmwarePerformanceGuid ## CONSUMES ## SystemTable + +[Protocols] + gEfiLoadedImageProtocolGuid ## CONSUMES + gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES + gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + gEfiShellDynamicCommandProtocolGuid ## PRODUCES + +[DEPEX] + TRUE diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h index 97f47f2960..8561bdaa67 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h @@ -1,315 +1,315 @@ -/** @file
- Declarations of objects defined internally to the Dp Application.
-
- Declarations of data and functions which are private to the Dp application.
- This file should never be referenced by anything other than components of the
- Dp application. In addition to global data, function declarations for
- DpUtilities.c, DpTrace.c, and DpProfile.c are included here.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef _DP_INTELNAL_H_
-#define _DP_INTELNAL_H_
-
-#define DP_GAUGE_STRING_LENGTH 36
-
-//
-/// Module-Global Variables
-///@{
-extern EFI_HII_HANDLE mDpHiiHandle;
-extern CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
-extern CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
-extern UINT64 mInterestThreshold;
-extern BOOLEAN mShowId;
-extern UINT8 *mBootPerformanceTable;
-extern UINTN mBootPerformanceTableLength;
-extern MEASUREMENT_RECORD *mMeasurementList;
-extern UINTN mMeasurementNum;
-extern UINT64 mResetEnd;
-
-extern PERF_SUMMARY_DATA SummaryData; ///< Create the SummaryData structure and init. to ZERO.
-
-/// Items for which to gather cumulative statistics.
-extern PERF_CUM_DATA CumData[];
-
-/// Number of items for which we are gathering cumulative statistics.
-extern UINT32 const NumCum;
-
-///@}
-
-/**
- Calculate an event's duration in timer ticks.
-
- Given the count direction and the event's start and end timer values,
- calculate the duration of the event in timer ticks. Information for
- the current measurement is pointed to by the parameter.
-
- If the measurement's start time is 1, it indicates that the developer
- is indicating that the measurement began at the release of reset.
- The start time is adjusted to the timer's starting count before performing
- the elapsed time calculation.
-
- The calculated duration, in ticks, is the absolute difference between
- the measurement's ending and starting counts.
-
- @param Measurement Pointer to a MEASUREMENT_RECORD structure containing
- data for the current measurement.
-
- @return The 64-bit duration of the event.
-**/
-UINT64
-GetDuration (
- IN OUT MEASUREMENT_RECORD *Measurement
- );
-
-/**
- Determine whether the Measurement record is for an EFI Phase.
-
- The Token and Module members of the measurement record are checked.
- Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.
-
- @param[in] Measurement A pointer to the Measurement record to test.
-
- @retval TRUE The measurement record is for an EFI Phase.
- @retval FALSE The measurement record is NOT for an EFI Phase.
-**/
-BOOLEAN
-IsPhase (
- IN MEASUREMENT_RECORD *Measurement
- );
-
-/**
- Determine whether the Measurement record is for core code.
-
- @param[in] Measurement A pointer to the Measurement record to test.
-
- @retval TRUE The measurement record is used for core.
- @retval FALSE The measurement record is NOT used for core.
-
-**/
-BOOLEAN
-IsCorePerf (
- IN MEASUREMENT_RECORD *Measurement
- );
-
-/**
- Get the file name portion of the Pdb File Name.
-
- The portion of the Pdb File Name between the last backslash and
- either a following period or the end of the string is converted
- to Unicode and copied into UnicodeBuffer. The name is truncated,
- if necessary, to ensure that UnicodeBuffer is not overrun.
-
- @param[in] PdbFileName Pdb file name.
- @param[out] UnicodeBuffer The resultant Unicode File Name.
-
-**/
-VOID
-DpGetShortPdbFileName (
- IN CHAR8 *PdbFileName,
- OUT CHAR16 *UnicodeBuffer
- );
-
-/**
- Get a human readable name for an image handle.
- The following methods will be tried orderly:
- 1. Image PDB
- 2. ComponentName2 protocol
- 3. FFS UI section
- 4. Image GUID
- 5. Image DevicePath
- 6. Unknown Driver Name
-
- @param[in] Handle
-
- @post The resulting Unicode name string is stored in the
- mGaugeString global array.
-
-**/
-VOID
-DpGetNameFromHandle (
- IN EFI_HANDLE Handle
- );
-
-/**
- Calculate the Duration in microseconds.
-
- Duration is multiplied by 1000, instead of Frequency being divided by 1000 or
- multiplying the result by 1000, in order to maintain precision. Since Duration is
- a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.
-
- The time is calculated as (Duration * 1000) / Timer_Frequency.
-
- @param[in] Duration The event duration in timer ticks.
-
- @return A 64-bit value which is the Elapsed time in microseconds.
-**/
-UINT64
-DurationInMicroSeconds (
- IN UINT64 Duration
- );
-
-/**
- Get index of Measurement Record's match in the CumData array.
-
- If the Measurement's Token value matches a Token in one of the CumData
- records, the index of the matching record is returned. The returned
- index is a signed value so that negative values can indicate that
- the Measurement didn't match any entry in the CumData array.
-
- @param[in] Measurement A pointer to a Measurement Record to match against the CumData array.
-
- @retval <0 Token is not in the CumData array.
- @retval >=0 Return value is the index into CumData where Token is found.
-**/
-INTN
-GetCumulativeItem (
- IN MEASUREMENT_RECORD *Measurement
- );
-
-/**
- Collect verbose statistics about the logged performance measurements.
-
- General Summary information for all Trace measurements is gathered and
- stored within the SummaryData structure. This information is both
- used internally by subsequent reporting functions, and displayed
- at the end of verbose reports.
-
- @pre The SummaryData and CumData structures must be initialized
- prior to calling this function.
-
- @post The SummaryData and CumData structures contain statistics for the
- current performance logs.
-
- @param[in, out] CustomCumulativeData The pointer to the custom cumulative data.
-
-**/
-VOID
-GatherStatistics (
- IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL
- );
-
-/**
- Gather and print ALL Trace Records.
-
- Displays all "interesting" Trace measurements in order.<BR>
- The number of records displayed is controlled by:
- - records with a duration less than mInterestThreshold microseconds are not displayed.
- - No more than Limit records are displayed. A Limit of zero will not limit the output.
- - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
- displayed.
-
- @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
- The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
- They must not be in use by a calling function.
-
- @param[in] Limit The number of records to print. Zero is ALL.
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
- @return Others from a call to gBS->LocateHandleBuffer().
-**/
-EFI_STATUS
-DumpAllTrace (
- IN UINTN Limit,
- IN BOOLEAN ExcludeFlag
- );
-
-/**
- Gather and print Raw Trace Records.
-
- All Trace measurements with a duration greater than or equal to
- mInterestThreshold are printed without interpretation.
-
- The number of records displayed is controlled by:
- - records with a duration less than mInterestThreshold microseconds are not displayed.
- - No more than Limit records are displayed. A Limit of zero will not limit the output.
- - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
- displayed.
-
- @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
-
- @param[in] Limit The number of records to print. Zero is ALL.
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-DumpRawTrace (
- IN UINTN Limit,
- IN BOOLEAN ExcludeFlag
- );
-
-/**
- Gather and print Major Phase metrics.
-
-**/
-VOID
-ProcessPhases (
- VOID
- );
-
-/**
- Gather and print Handle data.
-
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
- @return Others from a call to gBS->LocateHandleBuffer().
-**/
-EFI_STATUS
-ProcessHandles (
- IN BOOLEAN ExcludeFlag
- );
-
-/**
- Gather and print PEIM data.
-
- Only prints complete PEIM records
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-ProcessPeims (
- VOID
- );
-
-/**
- Gather and print global data.
-
- Strips out incomplete or "Execution Phase" records
- Only prints records where Handle is NULL
- Increment TIndex for every record, even skipped ones, so that we have an
- indication of every measurement record taken.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-ProcessGlobal (
- VOID
- );
-
-/**
- Gather and print cumulative data.
-
- Traverse the measurement records and:<BR>
- For each record with a Token listed in the CumData array:<BR>
- - Update the instance count and the total, minimum, and maximum durations.
- Finally, print the gathered cumulative statistics.
-
- @param[in] CustomCumulativeData The pointer to the custom cumulative data.
-
-**/
-VOID
-ProcessCumulative (
- IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL
- );
-
-#endif
+/** @file + Declarations of objects defined internally to the Dp Application. + + Declarations of data and functions which are private to the Dp application. + This file should never be referenced by anything other than components of the + Dp application. In addition to global data, function declarations for + DpUtilities.c, DpTrace.c, and DpProfile.c are included here. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. + (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _DP_INTELNAL_H_ +#define _DP_INTELNAL_H_ + +#define DP_GAUGE_STRING_LENGTH 36 + +// +/// Module-Global Variables +///@{ +extern EFI_HII_HANDLE mDpHiiHandle; +extern CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1]; +extern CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE]; +extern UINT64 mInterestThreshold; +extern BOOLEAN mShowId; +extern UINT8 *mBootPerformanceTable; +extern UINTN mBootPerformanceTableLength; +extern MEASUREMENT_RECORD *mMeasurementList; +extern UINTN mMeasurementNum; +extern UINT64 mResetEnd; + +extern PERF_SUMMARY_DATA SummaryData; ///< Create the SummaryData structure and init. to ZERO. + +/// Items for which to gather cumulative statistics. +extern PERF_CUM_DATA CumData[]; + +/// Number of items for which we are gathering cumulative statistics. +extern UINT32 const NumCum; + +///@} + +/** + Calculate an event's duration in timer ticks. + + Given the count direction and the event's start and end timer values, + calculate the duration of the event in timer ticks. Information for + the current measurement is pointed to by the parameter. + + If the measurement's start time is 1, it indicates that the developer + is indicating that the measurement began at the release of reset. + The start time is adjusted to the timer's starting count before performing + the elapsed time calculation. + + The calculated duration, in ticks, is the absolute difference between + the measurement's ending and starting counts. + + @param Measurement Pointer to a MEASUREMENT_RECORD structure containing + data for the current measurement. + + @return The 64-bit duration of the event. +**/ +UINT64 +GetDuration ( + IN OUT MEASUREMENT_RECORD *Measurement + ); + +/** + Determine whether the Measurement record is for an EFI Phase. + + The Token and Module members of the measurement record are checked. + Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is for an EFI Phase. + @retval FALSE The measurement record is NOT for an EFI Phase. +**/ +BOOLEAN +IsPhase ( + IN MEASUREMENT_RECORD *Measurement + ); + +/** + Determine whether the Measurement record is for core code. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is used for core. + @retval FALSE The measurement record is NOT used for core. + +**/ +BOOLEAN +IsCorePerf ( + IN MEASUREMENT_RECORD *Measurement + ); + +/** + Get the file name portion of the Pdb File Name. + + The portion of the Pdb File Name between the last backslash and + either a following period or the end of the string is converted + to Unicode and copied into UnicodeBuffer. The name is truncated, + if necessary, to ensure that UnicodeBuffer is not overrun. + + @param[in] PdbFileName Pdb file name. + @param[out] UnicodeBuffer The resultant Unicode File Name. + +**/ +VOID +DpGetShortPdbFileName ( + IN CHAR8 *PdbFileName, + OUT CHAR16 *UnicodeBuffer + ); + +/** + Get a human readable name for an image handle. + The following methods will be tried orderly: + 1. Image PDB + 2. ComponentName2 protocol + 3. FFS UI section + 4. Image GUID + 5. Image DevicePath + 6. Unknown Driver Name + + @param[in] Handle + + @post The resulting Unicode name string is stored in the + mGaugeString global array. + +**/ +VOID +DpGetNameFromHandle ( + IN EFI_HANDLE Handle + ); + +/** + Calculate the Duration in microseconds. + + Duration is multiplied by 1000, instead of Frequency being divided by 1000 or + multiplying the result by 1000, in order to maintain precision. Since Duration is + a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow. + + The time is calculated as (Duration * 1000) / Timer_Frequency. + + @param[in] Duration The event duration in timer ticks. + + @return A 64-bit value which is the Elapsed time in microseconds. +**/ +UINT64 +DurationInMicroSeconds ( + IN UINT64 Duration + ); + +/** + Get index of Measurement Record's match in the CumData array. + + If the Measurement's Token value matches a Token in one of the CumData + records, the index of the matching record is returned. The returned + index is a signed value so that negative values can indicate that + the Measurement didn't match any entry in the CumData array. + + @param[in] Measurement A pointer to a Measurement Record to match against the CumData array. + + @retval <0 Token is not in the CumData array. + @retval >=0 Return value is the index into CumData where Token is found. +**/ +INTN +GetCumulativeItem ( + IN MEASUREMENT_RECORD *Measurement + ); + +/** + Collect verbose statistics about the logged performance measurements. + + General Summary information for all Trace measurements is gathered and + stored within the SummaryData structure. This information is both + used internally by subsequent reporting functions, and displayed + at the end of verbose reports. + + @pre The SummaryData and CumData structures must be initialized + prior to calling this function. + + @post The SummaryData and CumData structures contain statistics for the + current performance logs. + + @param[in, out] CustomCumulativeData The pointer to the custom cumulative data. + +**/ +VOID +GatherStatistics ( + IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL + ); + +/** + Gather and print ALL Trace Records. + + Displays all "interesting" Trace measurements in order.<BR> + The number of records displayed is controlled by: + - records with a duration less than mInterestThreshold microseconds are not displayed. + - No more than Limit records are displayed. A Limit of zero will not limit the output. + - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not + displayed. + + @pre The mInterestThreshold global variable is set to the shortest duration to be printed. + The mGaugeString and mUnicodeToken global arrays are used for temporary string storage. + They must not be in use by a calling function. + + @param[in] Limit The number of records to print. Zero is ALL. + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. + @return Others from a call to gBS->LocateHandleBuffer(). +**/ +EFI_STATUS +DumpAllTrace ( + IN UINTN Limit, + IN BOOLEAN ExcludeFlag + ); + +/** + Gather and print Raw Trace Records. + + All Trace measurements with a duration greater than or equal to + mInterestThreshold are printed without interpretation. + + The number of records displayed is controlled by: + - records with a duration less than mInterestThreshold microseconds are not displayed. + - No more than Limit records are displayed. A Limit of zero will not limit the output. + - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not + displayed. + + @pre The mInterestThreshold global variable is set to the shortest duration to be printed. + + @param[in] Limit The number of records to print. Zero is ALL. + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +DumpRawTrace ( + IN UINTN Limit, + IN BOOLEAN ExcludeFlag + ); + +/** + Gather and print Major Phase metrics. + +**/ +VOID +ProcessPhases ( + VOID + ); + +/** + Gather and print Handle data. + + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. + @return Others from a call to gBS->LocateHandleBuffer(). +**/ +EFI_STATUS +ProcessHandles ( + IN BOOLEAN ExcludeFlag + ); + +/** + Gather and print PEIM data. + + Only prints complete PEIM records + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +ProcessPeims ( + VOID + ); + +/** + Gather and print global data. + + Strips out incomplete or "Execution Phase" records + Only prints records where Handle is NULL + Increment TIndex for every record, even skipped ones, so that we have an + indication of every measurement record taken. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +ProcessGlobal ( + VOID + ); + +/** + Gather and print cumulative data. + + Traverse the measurement records and:<BR> + For each record with a Token listed in the CumData array:<BR> + - Update the instance count and the total, minimum, and maximum durations. + Finally, print the gathered cumulative statistics. + + @param[in] CustomCumulativeData The pointer to the custom cumulative data. + +**/ +VOID +ProcessCumulative ( + IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL + ); + +#endif diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c index 9c0a9a06a1..0ac996743a 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c @@ -1,1050 +1,1050 @@ -/** @file
- Trace reporting for the Dp utility.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-#include <Library/PerformanceLib.h>
-#include <Library/PrintLib.h>
-#include <Library/HiiLib.h>
-#include <Library/PcdLib.h>
-
-#include "Dp.h"
-#include "Literals.h"
-#include "DpInternal.h"
-
-/**
- Attempts to retrieve a performance measurement log entry from the performance measurement log.
-
-
- @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
- 0, then the first performance measurement log entry is retrieved.
- On exit, the key of the next performance log entry.
- @param Handle Pointer to environment specific context used to identify the component
- being measured.
- @param Token Pointer to a Null-terminated ASCII string that identifies the component
- being measured.
- @param Module Pointer to a Null-terminated ASCII string that identifies the module
- being measured.
- @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
- was started.
- @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
- was ended.
- @param Identifier Pointer to the 32-bit identifier that was recorded when the measurement
- was ended.
-
- @return The key for the next performance log entry (in general case).
-
-**/
-UINTN
-GetPerformanceMeasurementRecord (
- IN UINTN LogEntryKey,
- OUT CONST VOID **Handle,
- OUT CONST CHAR8 **Token,
- OUT CONST CHAR8 **Module,
- OUT UINT64 *StartTimeStamp,
- OUT UINT64 *EndTimeStamp,
- OUT UINT32 *Identifier
- )
-{
- if (LogEntryKey == mMeasurementNum) {
- return 0;
- }
-
- *Handle = (VOID *)(UINTN)mMeasurementList[LogEntryKey].Handle;
- *Token = mMeasurementList[LogEntryKey].Token;
- *Module = mMeasurementList[LogEntryKey].Module;
- *StartTimeStamp = mMeasurementList[LogEntryKey].StartTimeStamp;
- *EndTimeStamp = mMeasurementList[LogEntryKey].EndTimeStamp;
- *Identifier = mMeasurementList[LogEntryKey].Identifier;
-
- LogEntryKey++;
-
- return LogEntryKey;
-}
-
-/**
- Collect verbose statistics about the logged performance measurements.
-
- General Summary information for all Trace measurements is gathered and
- stored within the SummaryData structure. This information is both
- used internally by subsequent reporting functions, and displayed
- at the end of verbose reports.
-
- @pre The SummaryData and CumData structures must be initialized
- prior to calling this function.
-
- @post The SummaryData and CumData structures contain statistics for the
- current performance logs.
-
- @param[in, out] CustomCumulativeData A pointer to the custom cumulative data.
-
-**/
-VOID
-GatherStatistics (
- IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 Duration;
- UINTN LogEntryKey;
- INTN TIndex;
-
- LogEntryKey = 0;
- while ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- {
- ++SummaryData.NumTrace; // Count the number of TRACE Measurement records
- if (Measurement.EndTimeStamp == 0) {
- ++SummaryData.NumIncomplete; // Count the incomplete records
- continue;
- }
-
- if (Measurement.Handle != NULL) {
- ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles
- }
-
- if (IsPhase (&Measurement)) {
- ++SummaryData.NumSummary; // Count the number of major phases
- } else {
- // !IsPhase
- if (Measurement.Handle == NULL) {
- ++SummaryData.NumGlobal;
- }
- }
-
- if (AsciiStrCmp (Measurement.Token, ALit_PEIM) == 0) {
- ++SummaryData.NumPEIMs; // Count PEIM measurements
- }
-
- Duration = GetDuration (&Measurement);
- TIndex = GetCumulativeItem (&Measurement);
- if (TIndex >= 0) {
- CumData[TIndex].Duration += Duration;
- CumData[TIndex].Count++;
- if ( Duration < CumData[TIndex].MinDur ) {
- CumData[TIndex].MinDur = Duration;
- }
-
- if ( Duration > CumData[TIndex].MaxDur ) {
- CumData[TIndex].MaxDur = Duration;
- }
- }
-
- //
- // Collect the data for custom cumulative data.
- //
- if ((CustomCumulativeData != NULL) && (AsciiStrCmp (Measurement.Token, CustomCumulativeData->Name) == 0)) {
- CustomCumulativeData->Duration += Duration;
- CustomCumulativeData->Count++;
- if (Duration < CustomCumulativeData->MinDur) {
- CustomCumulativeData->MinDur = Duration;
- }
-
- if (Duration > CustomCumulativeData->MaxDur) {
- CustomCumulativeData->MaxDur = Duration;
- }
- }
- }
-}
-
-/**
- Gather and print ALL Trace Records.
-
- Displays all "interesting" Trace measurements in order.<BR>
- The number of records displayed is controlled by:
- - records with a duration less than mInterestThreshold microseconds are not displayed.
- - No more than Limit records are displayed. A Limit of zero will not limit the output.
- - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
- displayed.
-
- @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
- The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
- They must not be in use by a calling function.
-
- @param[in] Limit The number of records to print. Zero is ALL.
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
- @return Others from a call to gBS->LocateHandleBuffer().
-**/
-EFI_STATUS
-DumpAllTrace (
- IN UINTN Limit,
- IN BOOLEAN ExcludeFlag
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 ElapsedTime;
- UINT64 Duration;
- CHAR16 *IncFlag;
- UINTN LogEntryKey;
- UINTN Count;
- UINTN Index;
- UINTN TIndex;
-
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- EFI_STATUS Status;
- EFI_STRING StringPtrUnknown;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (IncFlag == NULL) ? StringPtrUnknown : IncFlag
- );
- FreePool (StringPtrUnknown);
-
- // Get Handle information
- //
- Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
- } else {
- // We have successfully populated the HandleBuffer
- // Display ALL Measurement Records
- // Up to Limit lines displayed
- // Display only records with Elapsed times >= mInterestThreshold
- // Display driver names in Module field for records with Handles.
- //
- if (mShowId) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), mDpHiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);
- }
-
- LogEntryKey = 0;
- Count = 0;
- Index = 0;
- while ( WITHIN_LIMIT (Count, Limit) &&
- ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- )
- {
- ++Index; // Count every record. First record is 1.
- ElapsedTime = 0;
- SHELL_FREE_NON_NULL (IncFlag);
- if (Measurement.EndTimeStamp != 0) {
- Duration = GetDuration (&Measurement);
- ElapsedTime = DurationInMicroSeconds (Duration);
- IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);
- } else {
- IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records
- }
-
- if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
- ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0))
- ) // Ignore "uninteresting" or excluded records
- {
- continue;
- }
-
- ++Count; // Count the number of records printed
-
- // If Handle is non-zero, see if we can determine a name for the driver
- AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); // Use Module by default
- AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
- if (Measurement.Handle != NULL) {
- // See if the Handle is in the HandleBuffer
- for (TIndex = 0; TIndex < HandleCount; TIndex++) {
- if (Measurement.Handle == HandleBuffer[TIndex]) {
- DpGetNameFromHandle (HandleBuffer[TIndex]);
- break;
- }
- }
- }
-
- if (AsciiStrCmp (Measurement.Token, ALit_PEIM) == 0) {
- UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
- }
-
- // Ensure that the argument strings are not too long.
- mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
- mUnicodeToken[13] = 0;
-
- if (mShowId) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_ALL_VARS2),
- mDpHiiHandle,
- Index, // 1 based, Which measurement record is being printed
- IncFlag,
- Measurement.Handle,
- mGaugeString,
- mUnicodeToken,
- ElapsedTime,
- Measurement.Identifier
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_ALL_VARS),
- mDpHiiHandle,
- Index, // 1 based, Which measurement record is being printed
- IncFlag,
- Measurement.Handle,
- mGaugeString,
- mUnicodeToken,
- ElapsedTime
- );
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
- }
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- SHELL_FREE_NON_NULL (IncFlag);
-
- return Status;
-}
-
-/**
- Gather and print Raw Trace Records.
-
- All Trace measurements with a duration greater than or equal to
- mInterestThreshold are printed without interpretation.
-
- The number of records displayed is controlled by:
- - records with a duration less than mInterestThreshold microseconds are not displayed.
- - No more than Limit records are displayed. A Limit of zero will not limit the output.
- - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
- displayed.
-
- @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
-
- @param[in] Limit The number of records to print. Zero is ALL.
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-DumpRawTrace (
- IN UINTN Limit,
- IN BOOLEAN ExcludeFlag
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 ElapsedTime;
- UINT64 Duration;
- UINTN LogEntryKey;
- UINTN Count;
- UINTN Index;
-
- EFI_STRING StringPtr;
- EFI_STRING StringPtrUnknown;
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- if (mShowId) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), mDpHiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), mDpHiiHandle);
- }
-
- LogEntryKey = 0;
- Count = 0;
- Index = 0;
- while ( WITHIN_LIMIT (Count, Limit) &&
- ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- )
- {
- ++Index; // Count every record. First record is 1.
- ElapsedTime = 0;
- if (Measurement.EndTimeStamp != 0) {
- Duration = GetDuration (&Measurement);
- ElapsedTime = DurationInMicroSeconds (Duration);
- }
-
- if ((ElapsedTime < mInterestThreshold) ||
- ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0))
- ) // Ignore "uninteresting" or Excluded records
- {
- continue;
- }
-
- ++Count; // Count the number of records printed
-
- if (mShowId) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_RAW_VARS2),
- mDpHiiHandle,
- Index, // 1 based, Which measurement record is being printed
- Measurement.Handle,
- Measurement.StartTimeStamp,
- Measurement.EndTimeStamp,
- Measurement.Token,
- Measurement.Module,
- Measurement.Identifier
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_RAW_VARS),
- mDpHiiHandle,
- Index, // 1 based, Which measurement record is being printed
- Measurement.Handle,
- Measurement.StartTimeStamp,
- Measurement.EndTimeStamp,
- Measurement.Token,
- Measurement.Module
- );
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
- }
-
- return Status;
-}
-
-/**
- Gather and print Major Phase metrics.
-
-**/
-VOID
-ProcessPhases (
- VOID
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 BdsTimeoutValue;
- UINT64 SecTime;
- UINT64 PeiTime;
- UINT64 DxeTime;
- UINT64 BdsTime;
- UINT64 ElapsedTime;
- UINT64 Duration;
- UINT64 Total;
- EFI_STRING StringPtr;
- UINTN LogEntryKey;
- EFI_STRING StringPtrUnknown;
-
- BdsTimeoutValue = 0;
- SecTime = 0;
- PeiTime = 0;
- DxeTime = 0;
- BdsTime = 0;
- //
- // Get Execution Phase Statistics
- //
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- LogEntryKey = 0;
- while ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- {
- if (Measurement.EndTimeStamp == 0) {
- // Skip "incomplete" records
- continue;
- }
-
- Duration = GetDuration (&Measurement);
- if ( (Measurement.Handle != NULL)
- && (AsciiStrCmp (Measurement.Token, ALit_BdsTO) == 0)
- )
- {
- BdsTimeoutValue = Duration;
- } else if (AsciiStrCmp (Measurement.Token, ALit_SEC) == 0) {
- SecTime = Duration;
- } else if (AsciiStrCmp (Measurement.Token, ALit_PEI) == 0) {
- PeiTime = Duration;
- } else if (AsciiStrCmp (Measurement.Token, ALit_DXE) == 0) {
- DxeTime = Duration;
- } else if (AsciiStrCmp (Measurement.Token, ALit_BDS) == 0) {
- BdsTime = Duration;
- }
- }
-
- Total = 0;
-
- // print Reset End if it's valid
- //
- if (SecTime > mResetEnd) {
- SecTime = SecTime - mResetEnd; // Calculate sec time duration start from the beginning of firmware image execution
- ElapsedTime = DurationInMicroSeconds (mResetEnd); // Calculate elapsed time in microseconds
- Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RESET_END), mDpHiiHandle, ElapsedTime);
- }
-
- // print SEC phase duration time
- //
- if (SecTime > 0) {
- ElapsedTime = DurationInMicroSeconds (SecTime); // Calculate elapsed time in microseconds
- Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), mDpHiiHandle, ElapsedTime);
- }
-
- // print PEI phase duration time
- //
- if (PeiTime > 0) {
- ElapsedTime = DivU64x32 (PeiTime, 1000000);
- Total += ElapsedTime;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_PEI, ElapsedTime);
- }
-
- // print DXE phase duration time
- //
- if (DxeTime > 0) {
- ElapsedTime = DivU64x32 (DxeTime, 1000000);
- Total += ElapsedTime;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_DXE, ElapsedTime);
- }
-
- // print BDS phase duration time
- //
- if (BdsTime > 0) {
- ElapsedTime = DivU64x32 (BdsTime, 1000000);
- Total += ElapsedTime;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_BDS, ElapsedTime);
- }
-
- if (BdsTimeoutValue > 0) {
- ElapsedTime = DivU64x32 (BdsTimeoutValue, 1000000);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), mDpHiiHandle, ALit_BdsTO, ElapsedTime);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), mDpHiiHandle, Total);
-}
-
-/**
- Gather and print Handle data.
-
- @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
- @return Others from a call to gBS->LocateHandleBuffer().
-**/
-EFI_STATUS
-ProcessHandles (
- IN BOOLEAN ExcludeFlag
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 ElapsedTime;
- UINT64 Duration;
- EFI_HANDLE *HandleBuffer;
- EFI_STRING StringPtr;
- UINTN Index;
- UINTN LogEntryKey;
- UINTN Count;
- UINTN HandleCount;
- EFI_STATUS Status;
- EFI_STRING StringPtrUnknown;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
- } else {
- #if DP_DEBUG == 2
- Print (L"There are %,d Handles defined.\n", (Size / sizeof (HandleBuffer[0])));
- #endif
-
- if (mShowId) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), mDpHiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), mDpHiiHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);
-
- LogEntryKey = 0;
- Count = 0;
- while ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- {
- Count++;
- Duration = GetDuration (&Measurement);
- ElapsedTime = DurationInMicroSeconds (Duration);
- if ((ElapsedTime < mInterestThreshold) ||
- (Measurement.EndTimeStamp == 0) ||
- (!IsCorePerf (&Measurement)) ||
- ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0))
- ) // Ignore "uninteresting" or excluded records
- {
- continue;
- }
-
- mGaugeString[0] = 0; // Empty driver name by default
- AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
- // See if the Handle is in the HandleBuffer
- for (Index = 0; Index < HandleCount; Index++) {
- if (Measurement.Handle == HandleBuffer[Index]) {
- DpGetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
- break;
- }
- }
-
- // Ensure that the argument strings are not too long.
- mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
- mUnicodeToken[11] = 0;
- if (mGaugeString[0] != 0) {
- // Display the record if it has a valid handle.
- if (mShowId) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_HANDLE_VARS2),
- mDpHiiHandle,
- Count, // 1 based, Which measurement record is being printed
- Index + 1, // 1 based, Which handle is being printed
- mGaugeString,
- mUnicodeToken,
- ElapsedTime,
- Measurement.Identifier
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_HANDLE_VARS),
- mDpHiiHandle,
- Count, // 1 based, Which measurement record is being printed
- Index + 1, // 1 based, Which handle is being printed
- mGaugeString,
- mUnicodeToken,
- ElapsedTime
- );
- }
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
- }
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- return Status;
-}
-
-/**
- Gather and print PEIM data.
-
- Only prints complete PEIM records
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-ProcessPeims (
- VOID
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 Duration;
- UINT64 ElapsedTime;
- EFI_STRING StringPtr;
- UINTN LogEntryKey;
- UINTN TIndex;
- EFI_STRING StringPtrUnknown;
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- if (mShowId) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), mDpHiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), mDpHiiHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);
- TIndex = 0;
- LogEntryKey = 0;
- while ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- {
- TIndex++;
- if ((Measurement.EndTimeStamp == 0) ||
- (AsciiStrCmp (Measurement.Token, ALit_PEIM) != 0)
- )
- {
- continue;
- }
-
- Duration = GetDuration (&Measurement);
- ElapsedTime = DurationInMicroSeconds (Duration); // Calculate elapsed time in microseconds
- if (ElapsedTime >= mInterestThreshold) {
- // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
- if (mShowId) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_PEIM_VARS2),
- mDpHiiHandle,
- TIndex, // 1 based, Which measurement record is being printed
- Measurement.Handle, // file guid
- ElapsedTime,
- Measurement.Identifier
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_PEIM_VARS),
- mDpHiiHandle,
- TIndex, // 1 based, Which measurement record is being printed
- Measurement.Handle, // file guid
- ElapsedTime
- );
- }
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
- }
-
- return Status;
-}
-
-/**
- Gather and print global data.
-
- Strips out incomplete or "Execution Phase" records
- Only prints records where Handle is NULL
- Increment TIndex for every record, even skipped ones, so that we have an
- indication of every measurement record taken.
-
- @retval EFI_SUCCESS The operation was successful.
- @retval EFI_ABORTED The user aborts the operation.
-**/
-EFI_STATUS
-ProcessGlobal (
- VOID
- )
-{
- MEASUREMENT_RECORD Measurement;
- UINT64 Duration;
- UINT64 ElapsedTime;
- EFI_STRING StringPtr;
- UINTN LogEntryKey;
- UINTN Index; // Index, or number, of the measurement record being processed
- EFI_STRING StringPtrUnknown;
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- if (mShowId) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), mDpHiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), mDpHiiHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);
-
- Index = 1;
- LogEntryKey = 0;
-
- while ((LogEntryKey = GetPerformanceMeasurementRecord (
- LogEntryKey,
- &Measurement.Handle,
- &Measurement.Token,
- &Measurement.Module,
- &Measurement.StartTimeStamp,
- &Measurement.EndTimeStamp,
- &Measurement.Identifier
- )) != 0)
- {
- AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString));
- AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
- mGaugeString[25] = 0;
- mUnicodeToken[31] = 0;
- if ( !(IsPhase (&Measurement) ||
- IsCorePerf (&Measurement) ||
- (Measurement.EndTimeStamp == 0)
- ))
- {
- Duration = GetDuration (&Measurement);
- ElapsedTime = DurationInMicroSeconds (Duration);
- if (ElapsedTime >= mInterestThreshold) {
- if (mShowId) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_GLOBAL_VARS2),
- mDpHiiHandle,
- Index,
- mGaugeString,
- mUnicodeToken,
- ElapsedTime,
- Measurement.Identifier
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_GLOBAL_VARS),
- mDpHiiHandle,
- Index,
- mGaugeString,
- mUnicodeToken,
- ElapsedTime
- );
- }
- }
- }
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
-
- Index++;
- }
-
- return Status;
-}
-
-/**
- Gather and print cumulative data.
-
- Traverse the measurement records and:<BR>
- For each record with a Token listed in the CumData array:<BR>
- - Update the instance count and the total, minimum, and maximum durations.
- Finally, print the gathered cumulative statistics.
-
- @param[in] CustomCumulativeData A pointer to the custom cumulative data.
-
-**/
-VOID
-ProcessCumulative (
- IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL
- )
-{
- UINT64 AvgDur; // the computed average duration
- UINT64 Dur;
- UINT64 MinDur;
- UINT64 MaxDur;
- EFI_STRING StringPtr;
- UINTN TIndex;
- EFI_STRING StringPtrUnknown;
-
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- FreePool (StringPtr);
- FreePool (StringPtrUnknown);
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), mDpHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);
-
- for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
- if (CumData[TIndex].Count != 0) {
- AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
- AvgDur = DurationInMicroSeconds (AvgDur);
- Dur = DurationInMicroSeconds (CumData[TIndex].Duration);
- MaxDur = DurationInMicroSeconds (CumData[TIndex].MaxDur);
- MinDur = DurationInMicroSeconds (CumData[TIndex].MinDur);
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
- mDpHiiHandle,
- CumData[TIndex].Name,
- CumData[TIndex].Count,
- Dur,
- AvgDur,
- MinDur,
- MaxDur
- );
- }
- }
-
- //
- // Print the custom cumulative data.
- //
- if (CustomCumulativeData != NULL) {
- if (CustomCumulativeData->Count != 0) {
- AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count);
- AvgDur = DurationInMicroSeconds (AvgDur);
- Dur = DurationInMicroSeconds (CustomCumulativeData->Duration);
- MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur);
- MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur);
- } else {
- AvgDur = 0;
- Dur = 0;
- MaxDur = 0;
- MinDur = 0;
- }
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
- mDpHiiHandle,
- CustomCumulativeData->Name,
- CustomCumulativeData->Count,
- Dur,
- AvgDur,
- MinDur,
- MaxDur
- );
- }
-}
+/** @file + Trace reporting for the Dp utility. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. + (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/PeCoffGetEntryPointLib.h> +#include <Library/PerformanceLib.h> +#include <Library/PrintLib.h> +#include <Library/HiiLib.h> +#include <Library/PcdLib.h> + +#include "Dp.h" +#include "Literals.h" +#include "DpInternal.h" + +/** + Attempts to retrieve a performance measurement log entry from the performance measurement log. + + + @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve. + 0, then the first performance measurement log entry is retrieved. + On exit, the key of the next performance log entry. + @param Handle Pointer to environment specific context used to identify the component + being measured. + @param Token Pointer to a Null-terminated ASCII string that identifies the component + being measured. + @param Module Pointer to a Null-terminated ASCII string that identifies the module + being measured. + @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was started. + @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement + was ended. + @param Identifier Pointer to the 32-bit identifier that was recorded when the measurement + was ended. + + @return The key for the next performance log entry (in general case). + +**/ +UINTN +GetPerformanceMeasurementRecord ( + IN UINTN LogEntryKey, + OUT CONST VOID **Handle, + OUT CONST CHAR8 **Token, + OUT CONST CHAR8 **Module, + OUT UINT64 *StartTimeStamp, + OUT UINT64 *EndTimeStamp, + OUT UINT32 *Identifier + ) +{ + if (LogEntryKey == mMeasurementNum) { + return 0; + } + + *Handle = (VOID *)(UINTN)mMeasurementList[LogEntryKey].Handle; + *Token = mMeasurementList[LogEntryKey].Token; + *Module = mMeasurementList[LogEntryKey].Module; + *StartTimeStamp = mMeasurementList[LogEntryKey].StartTimeStamp; + *EndTimeStamp = mMeasurementList[LogEntryKey].EndTimeStamp; + *Identifier = mMeasurementList[LogEntryKey].Identifier; + + LogEntryKey++; + + return LogEntryKey; +} + +/** + Collect verbose statistics about the logged performance measurements. + + General Summary information for all Trace measurements is gathered and + stored within the SummaryData structure. This information is both + used internally by subsequent reporting functions, and displayed + at the end of verbose reports. + + @pre The SummaryData and CumData structures must be initialized + prior to calling this function. + + @post The SummaryData and CumData structures contain statistics for the + current performance logs. + + @param[in, out] CustomCumulativeData A pointer to the custom cumulative data. + +**/ +VOID +GatherStatistics ( + IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 Duration; + UINTN LogEntryKey; + INTN TIndex; + + LogEntryKey = 0; + while ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + { + ++SummaryData.NumTrace; // Count the number of TRACE Measurement records + if (Measurement.EndTimeStamp == 0) { + ++SummaryData.NumIncomplete; // Count the incomplete records + continue; + } + + if (Measurement.Handle != NULL) { + ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles + } + + if (IsPhase (&Measurement)) { + ++SummaryData.NumSummary; // Count the number of major phases + } else { + // !IsPhase + if (Measurement.Handle == NULL) { + ++SummaryData.NumGlobal; + } + } + + if (AsciiStrCmp (Measurement.Token, ALit_PEIM) == 0) { + ++SummaryData.NumPEIMs; // Count PEIM measurements + } + + Duration = GetDuration (&Measurement); + TIndex = GetCumulativeItem (&Measurement); + if (TIndex >= 0) { + CumData[TIndex].Duration += Duration; + CumData[TIndex].Count++; + if ( Duration < CumData[TIndex].MinDur ) { + CumData[TIndex].MinDur = Duration; + } + + if ( Duration > CumData[TIndex].MaxDur ) { + CumData[TIndex].MaxDur = Duration; + } + } + + // + // Collect the data for custom cumulative data. + // + if ((CustomCumulativeData != NULL) && (AsciiStrCmp (Measurement.Token, CustomCumulativeData->Name) == 0)) { + CustomCumulativeData->Duration += Duration; + CustomCumulativeData->Count++; + if (Duration < CustomCumulativeData->MinDur) { + CustomCumulativeData->MinDur = Duration; + } + + if (Duration > CustomCumulativeData->MaxDur) { + CustomCumulativeData->MaxDur = Duration; + } + } + } +} + +/** + Gather and print ALL Trace Records. + + Displays all "interesting" Trace measurements in order.<BR> + The number of records displayed is controlled by: + - records with a duration less than mInterestThreshold microseconds are not displayed. + - No more than Limit records are displayed. A Limit of zero will not limit the output. + - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not + displayed. + + @pre The mInterestThreshold global variable is set to the shortest duration to be printed. + The mGaugeString and mUnicodeToken global arrays are used for temporary string storage. + They must not be in use by a calling function. + + @param[in] Limit The number of records to print. Zero is ALL. + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. + @return Others from a call to gBS->LocateHandleBuffer(). +**/ +EFI_STATUS +DumpAllTrace ( + IN UINTN Limit, + IN BOOLEAN ExcludeFlag + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 ElapsedTime; + UINT64 Duration; + CHAR16 *IncFlag; + UINTN LogEntryKey; + UINTN Count; + UINTN Index; + UINTN TIndex; + + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + EFI_STATUS Status; + EFI_STRING StringPtrUnknown; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (IncFlag == NULL) ? StringPtrUnknown : IncFlag + ); + FreePool (StringPtrUnknown); + + // Get Handle information + // + Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status); + } else { + // We have successfully populated the HandleBuffer + // Display ALL Measurement Records + // Up to Limit lines displayed + // Display only records with Elapsed times >= mInterestThreshold + // Display driver names in Module field for records with Handles. + // + if (mShowId) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), mDpHiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle); + } + + LogEntryKey = 0; + Count = 0; + Index = 0; + while ( WITHIN_LIMIT (Count, Limit) && + ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + ) + { + ++Index; // Count every record. First record is 1. + ElapsedTime = 0; + SHELL_FREE_NON_NULL (IncFlag); + if (Measurement.EndTimeStamp != 0) { + Duration = GetDuration (&Measurement); + ElapsedTime = DurationInMicroSeconds (Duration); + IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL); + } else { + IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records + } + + if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) || + ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0)) + ) // Ignore "uninteresting" or excluded records + { + continue; + } + + ++Count; // Count the number of records printed + + // If Handle is non-zero, see if we can determine a name for the driver + AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); // Use Module by default + AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken)); + if (Measurement.Handle != NULL) { + // See if the Handle is in the HandleBuffer + for (TIndex = 0; TIndex < HandleCount; TIndex++) { + if (Measurement.Handle == HandleBuffer[TIndex]) { + DpGetNameFromHandle (HandleBuffer[TIndex]); + break; + } + } + } + + if (AsciiStrCmp (Measurement.Token, ALit_PEIM) == 0) { + UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle); + } + + // Ensure that the argument strings are not too long. + mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; + mUnicodeToken[13] = 0; + + if (mShowId) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_ALL_VARS2), + mDpHiiHandle, + Index, // 1 based, Which measurement record is being printed + IncFlag, + Measurement.Handle, + mGaugeString, + mUnicodeToken, + ElapsedTime, + Measurement.Identifier + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_ALL_VARS), + mDpHiiHandle, + Index, // 1 based, Which measurement record is being printed + IncFlag, + Measurement.Handle, + mGaugeString, + mUnicodeToken, + ElapsedTime + ); + } + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + } + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + SHELL_FREE_NON_NULL (IncFlag); + + return Status; +} + +/** + Gather and print Raw Trace Records. + + All Trace measurements with a duration greater than or equal to + mInterestThreshold are printed without interpretation. + + The number of records displayed is controlled by: + - records with a duration less than mInterestThreshold microseconds are not displayed. + - No more than Limit records are displayed. A Limit of zero will not limit the output. + - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not + displayed. + + @pre The mInterestThreshold global variable is set to the shortest duration to be printed. + + @param[in] Limit The number of records to print. Zero is ALL. + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +DumpRawTrace ( + IN UINTN Limit, + IN BOOLEAN ExcludeFlag + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 ElapsedTime; + UINT64 Duration; + UINTN LogEntryKey; + UINTN Count; + UINTN Index; + + EFI_STRING StringPtr; + EFI_STRING StringPtrUnknown; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + if (mShowId) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), mDpHiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), mDpHiiHandle); + } + + LogEntryKey = 0; + Count = 0; + Index = 0; + while ( WITHIN_LIMIT (Count, Limit) && + ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + ) + { + ++Index; // Count every record. First record is 1. + ElapsedTime = 0; + if (Measurement.EndTimeStamp != 0) { + Duration = GetDuration (&Measurement); + ElapsedTime = DurationInMicroSeconds (Duration); + } + + if ((ElapsedTime < mInterestThreshold) || + ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0)) + ) // Ignore "uninteresting" or Excluded records + { + continue; + } + + ++Count; // Count the number of records printed + + if (mShowId) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_RAW_VARS2), + mDpHiiHandle, + Index, // 1 based, Which measurement record is being printed + Measurement.Handle, + Measurement.StartTimeStamp, + Measurement.EndTimeStamp, + Measurement.Token, + Measurement.Module, + Measurement.Identifier + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_RAW_VARS), + mDpHiiHandle, + Index, // 1 based, Which measurement record is being printed + Measurement.Handle, + Measurement.StartTimeStamp, + Measurement.EndTimeStamp, + Measurement.Token, + Measurement.Module + ); + } + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + } + + return Status; +} + +/** + Gather and print Major Phase metrics. + +**/ +VOID +ProcessPhases ( + VOID + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 BdsTimeoutValue; + UINT64 SecTime; + UINT64 PeiTime; + UINT64 DxeTime; + UINT64 BdsTime; + UINT64 ElapsedTime; + UINT64 Duration; + UINT64 Total; + EFI_STRING StringPtr; + UINTN LogEntryKey; + EFI_STRING StringPtrUnknown; + + BdsTimeoutValue = 0; + SecTime = 0; + PeiTime = 0; + DxeTime = 0; + BdsTime = 0; + // + // Get Execution Phase Statistics + // + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + LogEntryKey = 0; + while ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + { + if (Measurement.EndTimeStamp == 0) { + // Skip "incomplete" records + continue; + } + + Duration = GetDuration (&Measurement); + if ( (Measurement.Handle != NULL) + && (AsciiStrCmp (Measurement.Token, ALit_BdsTO) == 0) + ) + { + BdsTimeoutValue = Duration; + } else if (AsciiStrCmp (Measurement.Token, ALit_SEC) == 0) { + SecTime = Duration; + } else if (AsciiStrCmp (Measurement.Token, ALit_PEI) == 0) { + PeiTime = Duration; + } else if (AsciiStrCmp (Measurement.Token, ALit_DXE) == 0) { + DxeTime = Duration; + } else if (AsciiStrCmp (Measurement.Token, ALit_BDS) == 0) { + BdsTime = Duration; + } + } + + Total = 0; + + // print Reset End if it's valid + // + if (SecTime > mResetEnd) { + SecTime = SecTime - mResetEnd; // Calculate sec time duration start from the beginning of firmware image execution + ElapsedTime = DurationInMicroSeconds (mResetEnd); // Calculate elapsed time in microseconds + Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RESET_END), mDpHiiHandle, ElapsedTime); + } + + // print SEC phase duration time + // + if (SecTime > 0) { + ElapsedTime = DurationInMicroSeconds (SecTime); // Calculate elapsed time in microseconds + Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), mDpHiiHandle, ElapsedTime); + } + + // print PEI phase duration time + // + if (PeiTime > 0) { + ElapsedTime = DivU64x32 (PeiTime, 1000000); + Total += ElapsedTime; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_PEI, ElapsedTime); + } + + // print DXE phase duration time + // + if (DxeTime > 0) { + ElapsedTime = DivU64x32 (DxeTime, 1000000); + Total += ElapsedTime; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_DXE, ElapsedTime); + } + + // print BDS phase duration time + // + if (BdsTime > 0) { + ElapsedTime = DivU64x32 (BdsTime, 1000000); + Total += ElapsedTime; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_BDS, ElapsedTime); + } + + if (BdsTimeoutValue > 0) { + ElapsedTime = DivU64x32 (BdsTimeoutValue, 1000000); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), mDpHiiHandle, ALit_BdsTO, ElapsedTime); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), mDpHiiHandle, Total); +} + +/** + Gather and print Handle data. + + @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. + @return Others from a call to gBS->LocateHandleBuffer(). +**/ +EFI_STATUS +ProcessHandles ( + IN BOOLEAN ExcludeFlag + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 ElapsedTime; + UINT64 Duration; + EFI_HANDLE *HandleBuffer; + EFI_STRING StringPtr; + UINTN Index; + UINTN LogEntryKey; + UINTN Count; + UINTN HandleCount; + EFI_STATUS Status; + EFI_STRING StringPtrUnknown; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status); + } else { + #if DP_DEBUG == 2 + Print (L"There are %,d Handles defined.\n", (Size / sizeof (HandleBuffer[0]))); + #endif + + if (mShowId) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), mDpHiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), mDpHiiHandle); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle); + + LogEntryKey = 0; + Count = 0; + while ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + { + Count++; + Duration = GetDuration (&Measurement); + ElapsedTime = DurationInMicroSeconds (Duration); + if ((ElapsedTime < mInterestThreshold) || + (Measurement.EndTimeStamp == 0) || + (!IsCorePerf (&Measurement)) || + ((ExcludeFlag) && (GetCumulativeItem (&Measurement) >= 0)) + ) // Ignore "uninteresting" or excluded records + { + continue; + } + + mGaugeString[0] = 0; // Empty driver name by default + AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken)); + // See if the Handle is in the HandleBuffer + for (Index = 0; Index < HandleCount; Index++) { + if (Measurement.Handle == HandleBuffer[Index]) { + DpGetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString + break; + } + } + + // Ensure that the argument strings are not too long. + mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; + mUnicodeToken[11] = 0; + if (mGaugeString[0] != 0) { + // Display the record if it has a valid handle. + if (mShowId) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_HANDLE_VARS2), + mDpHiiHandle, + Count, // 1 based, Which measurement record is being printed + Index + 1, // 1 based, Which handle is being printed + mGaugeString, + mUnicodeToken, + ElapsedTime, + Measurement.Identifier + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_HANDLE_VARS), + mDpHiiHandle, + Count, // 1 based, Which measurement record is being printed + Index + 1, // 1 based, Which handle is being printed + mGaugeString, + mUnicodeToken, + ElapsedTime + ); + } + } + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + } + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return Status; +} + +/** + Gather and print PEIM data. + + Only prints complete PEIM records + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +ProcessPeims ( + VOID + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 Duration; + UINT64 ElapsedTime; + EFI_STRING StringPtr; + UINTN LogEntryKey; + UINTN TIndex; + EFI_STRING StringPtrUnknown; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + if (mShowId) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), mDpHiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), mDpHiiHandle); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle); + TIndex = 0; + LogEntryKey = 0; + while ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + { + TIndex++; + if ((Measurement.EndTimeStamp == 0) || + (AsciiStrCmp (Measurement.Token, ALit_PEIM) != 0) + ) + { + continue; + } + + Duration = GetDuration (&Measurement); + ElapsedTime = DurationInMicroSeconds (Duration); // Calculate elapsed time in microseconds + if (ElapsedTime >= mInterestThreshold) { + // PEIM FILE Handle is the start address of its FFS file that contains its file guid. + if (mShowId) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_PEIM_VARS2), + mDpHiiHandle, + TIndex, // 1 based, Which measurement record is being printed + Measurement.Handle, // file guid + ElapsedTime, + Measurement.Identifier + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_PEIM_VARS), + mDpHiiHandle, + TIndex, // 1 based, Which measurement record is being printed + Measurement.Handle, // file guid + ElapsedTime + ); + } + } + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + } + + return Status; +} + +/** + Gather and print global data. + + Strips out incomplete or "Execution Phase" records + Only prints records where Handle is NULL + Increment TIndex for every record, even skipped ones, so that we have an + indication of every measurement record taken. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The user aborts the operation. +**/ +EFI_STATUS +ProcessGlobal ( + VOID + ) +{ + MEASUREMENT_RECORD Measurement; + UINT64 Duration; + UINT64 ElapsedTime; + EFI_STRING StringPtr; + UINTN LogEntryKey; + UINTN Index; // Index, or number, of the measurement record being processed + EFI_STRING StringPtrUnknown; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + if (mShowId) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), mDpHiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), mDpHiiHandle); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle); + + Index = 1; + LogEntryKey = 0; + + while ((LogEntryKey = GetPerformanceMeasurementRecord ( + LogEntryKey, + &Measurement.Handle, + &Measurement.Token, + &Measurement.Module, + &Measurement.StartTimeStamp, + &Measurement.EndTimeStamp, + &Measurement.Identifier + )) != 0) + { + AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); + AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken)); + mGaugeString[25] = 0; + mUnicodeToken[31] = 0; + if ( !(IsPhase (&Measurement) || + IsCorePerf (&Measurement) || + (Measurement.EndTimeStamp == 0) + )) + { + Duration = GetDuration (&Measurement); + ElapsedTime = DurationInMicroSeconds (Duration); + if (ElapsedTime >= mInterestThreshold) { + if (mShowId) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_GLOBAL_VARS2), + mDpHiiHandle, + Index, + mGaugeString, + mUnicodeToken, + ElapsedTime, + Measurement.Identifier + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_GLOBAL_VARS), + mDpHiiHandle, + Index, + mGaugeString, + mUnicodeToken, + ElapsedTime + ); + } + } + } + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + + Index++; + } + + return Status; +} + +/** + Gather and print cumulative data. + + Traverse the measurement records and:<BR> + For each record with a Token listed in the CumData array:<BR> + - Update the instance count and the total, minimum, and maximum durations. + Finally, print the gathered cumulative statistics. + + @param[in] CustomCumulativeData A pointer to the custom cumulative data. + +**/ +VOID +ProcessCumulative ( + IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL + ) +{ + UINT64 AvgDur; // the computed average duration + UINT64 Dur; + UINT64 MinDur; + UINT64 MaxDur; + EFI_STRING StringPtr; + UINTN TIndex; + EFI_STRING StringPtrUnknown; + + StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_SECTION_HEADER), + mDpHiiHandle, + (StringPtr == NULL) ? StringPtrUnknown : StringPtr + ); + FreePool (StringPtr); + FreePool (StringPtrUnknown); + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), mDpHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle); + + for ( TIndex = 0; TIndex < NumCum; ++TIndex) { + if (CumData[TIndex].Count != 0) { + AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count); + AvgDur = DurationInMicroSeconds (AvgDur); + Dur = DurationInMicroSeconds (CumData[TIndex].Duration); + MaxDur = DurationInMicroSeconds (CumData[TIndex].MaxDur); + MinDur = DurationInMicroSeconds (CumData[TIndex].MinDur); + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_CUMULATIVE_STATS), + mDpHiiHandle, + CumData[TIndex].Name, + CumData[TIndex].Count, + Dur, + AvgDur, + MinDur, + MaxDur + ); + } + } + + // + // Print the custom cumulative data. + // + if (CustomCumulativeData != NULL) { + if (CustomCumulativeData->Count != 0) { + AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count); + AvgDur = DurationInMicroSeconds (AvgDur); + Dur = DurationInMicroSeconds (CustomCumulativeData->Duration); + MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur); + MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur); + } else { + AvgDur = 0; + Dur = 0; + MaxDur = 0; + MinDur = 0; + } + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_DP_CUMULATIVE_STATS), + mDpHiiHandle, + CustomCumulativeData->Name, + CustomCumulativeData->Count, + Dur, + AvgDur, + MinDur, + MaxDur + ); + } +} diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c index 60c886c11d..725e628a2c 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c @@ -1,427 +1,427 @@ -/** @file
- Utility functions used by the Dp application.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-#include <Library/PrintLib.h>
-#include <Library/HiiLib.h>
-#include <Library/PcdLib.h>
-#include <Library/UefiLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HandleParsingLib.h>
-
-#include <Pi/PiFirmwareFile.h>
-#include <Library/DxeServicesLib.h>
-
-#include <Protocol/LoadedImage.h>
-#include <Protocol/DriverBinding.h>
-#include <Protocol/ComponentName2.h>
-#include <Protocol/DevicePath.h>
-
-#include <Guid/Performance.h>
-
-#include "Dp.h"
-#include "Literals.h"
-#include "DpInternal.h"
-
-/**
- Calculate an event's duration in timer ticks.
-
- Given the count direction and the event's start and end timer values,
- calculate the duration of the event in timer ticks. Information for
- the current measurement is pointed to by the parameter.
-
- If the measurement's start time is 1, it indicates that the developer
- is indicating that the measurement began at the release of reset.
- The start time is adjusted to the timer's starting count before performing
- the elapsed time calculation.
-
- The calculated duration, in ticks, is the absolute difference between
- the measurement's ending and starting counts.
-
- @param Measurement Pointer to a MEASUREMENT_RECORD structure containing
- data for the current measurement.
-
- @return The 64-bit duration of the event.
-**/
-UINT64
-GetDuration (
- IN OUT MEASUREMENT_RECORD *Measurement
- )
-{
- UINT64 Duration;
- BOOLEAN Error;
-
- if (Measurement->EndTimeStamp == 0) {
- return 0;
- }
-
- Duration = Measurement->EndTimeStamp - Measurement->StartTimeStamp;
- Error = (BOOLEAN)(Duration > Measurement->EndTimeStamp);
-
- if (Error) {
- DEBUG ((DEBUG_ERROR, ALit_TimerLibError));
- Duration = 0;
- }
-
- return Duration;
-}
-
-/**
- Determine whether the Measurement record is for an EFI Phase.
-
- The Token and Module members of the measurement record are checked.
- Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.
-
- @param[in] Measurement A pointer to the Measurement record to test.
-
- @retval TRUE The measurement record is for an EFI Phase.
- @retval FALSE The measurement record is NOT for an EFI Phase.
-**/
-BOOLEAN
-IsPhase (
- IN MEASUREMENT_RECORD *Measurement
- )
-{
- BOOLEAN RetVal;
-
- RetVal = (BOOLEAN)(
- ((AsciiStrCmp (Measurement->Token, ALit_SEC) == 0) ||
- (AsciiStrCmp (Measurement->Token, ALit_PEI) == 0) ||
- (AsciiStrCmp (Measurement->Token, ALit_DXE) == 0) ||
- (AsciiStrCmp (Measurement->Token, ALit_BDS) == 0))
- );
- return RetVal;
-}
-
-/**
- Determine whether the Measurement record is for core code.
-
- @param[in] Measurement A pointer to the Measurement record to test.
-
- @retval TRUE The measurement record is used for core.
- @retval FALSE The measurement record is NOT used for core.
-
-**/
-BOOLEAN
-IsCorePerf (
- IN MEASUREMENT_RECORD *Measurement
- )
-{
- BOOLEAN RetVal;
-
- RetVal = (BOOLEAN)(
- ((Measurement->Identifier == MODULE_START_ID) ||
- (Measurement->Identifier == MODULE_END_ID) ||
- (Measurement->Identifier == MODULE_LOADIMAGE_START_ID) ||
- (Measurement->Identifier == MODULE_LOADIMAGE_END_ID) ||
- (Measurement->Identifier == MODULE_DB_START_ID) ||
- (Measurement->Identifier == MODULE_DB_END_ID) ||
- (Measurement->Identifier == MODULE_DB_SUPPORT_START_ID) ||
- (Measurement->Identifier == MODULE_DB_SUPPORT_END_ID) ||
- (Measurement->Identifier == MODULE_DB_STOP_START_ID) ||
- (Measurement->Identifier == MODULE_DB_STOP_START_ID))
- );
- return RetVal;
-}
-
-/**
- Get the file name portion of the Pdb File Name.
-
- The portion of the Pdb File Name between the last backslash and
- either a following period or the end of the string is converted
- to Unicode and copied into UnicodeBuffer. The name is truncated,
- if necessary, to ensure that UnicodeBuffer is not overrun.
-
- @param[in] PdbFileName Pdb file name.
- @param[out] UnicodeBuffer The resultant Unicode File Name.
-
-**/
-VOID
-DpGetShortPdbFileName (
- IN CHAR8 *PdbFileName,
- OUT CHAR16 *UnicodeBuffer
- )
-{
- UINTN IndexA; // Current work location within an ASCII string.
- UINTN IndexU; // Current work location within a Unicode string.
- UINTN StartIndex;
- UINTN EndIndex;
-
- ZeroMem (UnicodeBuffer, (DP_GAUGE_STRING_LENGTH + 1) * sizeof (CHAR16));
-
- if (PdbFileName == NULL) {
- StrnCpyS (UnicodeBuffer, DP_GAUGE_STRING_LENGTH + 1, L" ", 1);
- } else {
- StartIndex = 0;
- for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) {
- }
-
- for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) {
- if ((PdbFileName[IndexA] == '\\') || (PdbFileName[IndexA] == '/')) {
- StartIndex = IndexA + 1;
- }
-
- if (PdbFileName[IndexA] == '.') {
- EndIndex = IndexA;
- }
- }
-
- IndexU = 0;
- for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) {
- UnicodeBuffer[IndexU] = (CHAR16)PdbFileName[IndexA];
- IndexU++;
- if (IndexU >= DP_GAUGE_STRING_LENGTH) {
- UnicodeBuffer[DP_GAUGE_STRING_LENGTH] = 0;
- break;
- }
- }
- }
-}
-
-/**
- Get a human readable name for an image handle.
- The following methods will be tried orderly:
- 1. Image PDB
- 2. ComponentName2 protocol
- 3. FFS UI section
- 4. Image GUID
- 5. Image DevicePath
- 6. Unknown Driver Name
-
- @param[in] Handle
-
- @post The resulting Unicode name string is stored in the
- mGaugeString global array.
-
-**/
-VOID
-DpGetNameFromHandle (
- IN EFI_HANDLE Handle
- )
-{
- EFI_STATUS Status;
- EFI_LOADED_IMAGE_PROTOCOL *Image;
- CHAR8 *PdbFileName;
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
- EFI_STRING StringPtr;
- EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_GUID *NameGuid;
- CHAR16 *NameString;
- UINTN StringSize;
- CHAR8 *PlatformLanguage;
- CHAR8 *BestLanguage;
- EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
-
- Image = NULL;
- LoadedImageDevicePath = NULL;
- DevicePath = NULL;
-
- //
- // Method 1: Get the name string from image PDB
- //
- 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)) {
- Status = gBS->HandleProtocol (
- DriverBinding->ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&Image
- );
- }
- }
-
- if (!EFI_ERROR (Status)) {
- PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
-
- if (PdbFileName != NULL) {
- DpGetShortPdbFileName (PdbFileName, mGaugeString);
- return;
- }
- }
-
- //
- // Method 2: Get the name string from ComponentName2 protocol
- //
- Status = gBS->HandleProtocol (
- Handle,
- &gEfiComponentName2ProtocolGuid,
- (VOID **)&ComponentName2
- );
- if (!EFI_ERROR (Status)) {
- //
- // Firstly use platform language setting, secondly use driver's first supported language.
- //
- GetVariable2 (L"PlatformLang", &gEfiGlobalVariableGuid, (VOID **)&PlatformLanguage, NULL);
- BestLanguage = GetBestLanguage (
- ComponentName2->SupportedLanguages,
- FALSE,
- (PlatformLanguage != NULL) ? PlatformLanguage : "",
- ComponentName2->SupportedLanguages,
- NULL
- );
- SHELL_FREE_NON_NULL (PlatformLanguage);
-
- Status = ComponentName2->GetDriverName (
- ComponentName2,
- BestLanguage != NULL ? BestLanguage : "en-US",
- &StringPtr
- );
- if (!EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (BestLanguage);
- StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH);
- mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
- return;
- }
- }
-
- Status = gBS->HandleProtocol (
- Handle,
- &gEfiLoadedImageDevicePathProtocolGuid,
- (VOID **)&LoadedImageDevicePath
- );
- if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) {
- DevicePath = LoadedImageDevicePath;
- } else if (Image != NULL) {
- DevicePath = Image->FilePath;
- }
-
- if (DevicePath != NULL) {
- //
- // Try to get image GUID from image DevicePath
- //
- NameGuid = NULL;
- while (!IsDevicePathEndType (DevicePath)) {
- NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevicePath);
- if (NameGuid != NULL) {
- break;
- }
-
- DevicePath = NextDevicePathNode (DevicePath);
- }
-
- if (NameGuid != NULL) {
- //
- // Try to get the image's FFS UI section by image GUID
- //
- NameString = NULL;
- StringSize = 0;
- Status = GetSectionFromAnyFv (
- NameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- (VOID **)&NameString,
- &StringSize
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // Method 3. Get the name string from FFS UI section
- //
- StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH);
- mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
- FreePool (NameString);
- } else {
- //
- // Method 4: Get the name string from image GUID
- //
- UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid);
- }
-
- return;
- } else {
- //
- // Method 5: Get the name string from image DevicePath
- //
- NameString = ConvertDevicePathToText (DevicePath, TRUE, FALSE);
- if (NameString != NULL) {
- StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH);
- mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
- FreePool (NameString);
- return;
- }
- }
- }
-
- //
- // Method 6: Unknown Driver Name
- //
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL);
- ASSERT (StringPtr != NULL);
- StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH);
- FreePool (StringPtr);
-}
-
-/**
- Calculate the Duration in microseconds.
-
- Duration is multiplied by 1000, instead of Frequency being divided by 1000 or
- multiplying the result by 1000, in order to maintain precision. Since Duration is
- a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.
-
- The time is calculated as (Duration * 1000) / Timer_Frequency.
-
- @param[in] Duration The event duration in timer ticks.
-
- @return A 64-bit value which is the Elapsed time in microseconds.
-**/
-UINT64
-DurationInMicroSeconds (
- IN UINT64 Duration
- )
-{
- return DivU64x32 (Duration, 1000);
-}
-
-/**
- Get index of Measurement Record's match in the CumData array.
-
- If the Measurement's Token value matches a Token in one of the CumData
- records, the index of the matching record is returned. The returned
- index is a signed value so that negative values can indicate that
- the Measurement didn't match any entry in the CumData array.
-
- @param[in] Measurement A pointer to a Measurement Record to match against the CumData array.
-
- @retval <0 Token is not in the CumData array.
- @retval >=0 Return value is the index into CumData where Token is found.
-**/
-INTN
-GetCumulativeItem (
- IN MEASUREMENT_RECORD *Measurement
- )
-{
- INTN Index;
-
- for ( Index = 0; Index < (INTN)NumCum; ++Index) {
- if (AsciiStrCmp (Measurement->Token, CumData[Index].Name) == 0) {
- return Index; // Exit, we found a match
- }
- }
-
- // If the for loop exits, Token was not found.
- return -1; // Indicate failure
-}
+/** @file + Utility functions used by the Dp application. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved. + (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/PeCoffGetEntryPointLib.h> +#include <Library/PrintLib.h> +#include <Library/HiiLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/DevicePathLib.h> +#include <Library/HandleParsingLib.h> + +#include <Pi/PiFirmwareFile.h> +#include <Library/DxeServicesLib.h> + +#include <Protocol/LoadedImage.h> +#include <Protocol/DriverBinding.h> +#include <Protocol/ComponentName2.h> +#include <Protocol/DevicePath.h> + +#include <Guid/Performance.h> + +#include "Dp.h" +#include "Literals.h" +#include "DpInternal.h" + +/** + Calculate an event's duration in timer ticks. + + Given the count direction and the event's start and end timer values, + calculate the duration of the event in timer ticks. Information for + the current measurement is pointed to by the parameter. + + If the measurement's start time is 1, it indicates that the developer + is indicating that the measurement began at the release of reset. + The start time is adjusted to the timer's starting count before performing + the elapsed time calculation. + + The calculated duration, in ticks, is the absolute difference between + the measurement's ending and starting counts. + + @param Measurement Pointer to a MEASUREMENT_RECORD structure containing + data for the current measurement. + + @return The 64-bit duration of the event. +**/ +UINT64 +GetDuration ( + IN OUT MEASUREMENT_RECORD *Measurement + ) +{ + UINT64 Duration; + BOOLEAN Error; + + if (Measurement->EndTimeStamp == 0) { + return 0; + } + + Duration = Measurement->EndTimeStamp - Measurement->StartTimeStamp; + Error = (BOOLEAN)(Duration > Measurement->EndTimeStamp); + + if (Error) { + DEBUG ((DEBUG_ERROR, ALit_TimerLibError)); + Duration = 0; + } + + return Duration; +} + +/** + Determine whether the Measurement record is for an EFI Phase. + + The Token and Module members of the measurement record are checked. + Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is for an EFI Phase. + @retval FALSE The measurement record is NOT for an EFI Phase. +**/ +BOOLEAN +IsPhase ( + IN MEASUREMENT_RECORD *Measurement + ) +{ + BOOLEAN RetVal; + + RetVal = (BOOLEAN)( + ((AsciiStrCmp (Measurement->Token, ALit_SEC) == 0) || + (AsciiStrCmp (Measurement->Token, ALit_PEI) == 0) || + (AsciiStrCmp (Measurement->Token, ALit_DXE) == 0) || + (AsciiStrCmp (Measurement->Token, ALit_BDS) == 0)) + ); + return RetVal; +} + +/** + Determine whether the Measurement record is for core code. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is used for core. + @retval FALSE The measurement record is NOT used for core. + +**/ +BOOLEAN +IsCorePerf ( + IN MEASUREMENT_RECORD *Measurement + ) +{ + BOOLEAN RetVal; + + RetVal = (BOOLEAN)( + ((Measurement->Identifier == MODULE_START_ID) || + (Measurement->Identifier == MODULE_END_ID) || + (Measurement->Identifier == MODULE_LOADIMAGE_START_ID) || + (Measurement->Identifier == MODULE_LOADIMAGE_END_ID) || + (Measurement->Identifier == MODULE_DB_START_ID) || + (Measurement->Identifier == MODULE_DB_END_ID) || + (Measurement->Identifier == MODULE_DB_SUPPORT_START_ID) || + (Measurement->Identifier == MODULE_DB_SUPPORT_END_ID) || + (Measurement->Identifier == MODULE_DB_STOP_START_ID) || + (Measurement->Identifier == MODULE_DB_STOP_START_ID)) + ); + return RetVal; +} + +/** + Get the file name portion of the Pdb File Name. + + The portion of the Pdb File Name between the last backslash and + either a following period or the end of the string is converted + to Unicode and copied into UnicodeBuffer. The name is truncated, + if necessary, to ensure that UnicodeBuffer is not overrun. + + @param[in] PdbFileName Pdb file name. + @param[out] UnicodeBuffer The resultant Unicode File Name. + +**/ +VOID +DpGetShortPdbFileName ( + IN CHAR8 *PdbFileName, + OUT CHAR16 *UnicodeBuffer + ) +{ + UINTN IndexA; // Current work location within an ASCII string. + UINTN IndexU; // Current work location within a Unicode string. + UINTN StartIndex; + UINTN EndIndex; + + ZeroMem (UnicodeBuffer, (DP_GAUGE_STRING_LENGTH + 1) * sizeof (CHAR16)); + + if (PdbFileName == NULL) { + StrnCpyS (UnicodeBuffer, DP_GAUGE_STRING_LENGTH + 1, L" ", 1); + } else { + StartIndex = 0; + for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) { + } + + for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) { + if ((PdbFileName[IndexA] == '\\') || (PdbFileName[IndexA] == '/')) { + StartIndex = IndexA + 1; + } + + if (PdbFileName[IndexA] == '.') { + EndIndex = IndexA; + } + } + + IndexU = 0; + for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) { + UnicodeBuffer[IndexU] = (CHAR16)PdbFileName[IndexA]; + IndexU++; + if (IndexU >= DP_GAUGE_STRING_LENGTH) { + UnicodeBuffer[DP_GAUGE_STRING_LENGTH] = 0; + break; + } + } + } +} + +/** + Get a human readable name for an image handle. + The following methods will be tried orderly: + 1. Image PDB + 2. ComponentName2 protocol + 3. FFS UI section + 4. Image GUID + 5. Image DevicePath + 6. Unknown Driver Name + + @param[in] Handle + + @post The resulting Unicode name string is stored in the + mGaugeString global array. + +**/ +VOID +DpGetNameFromHandle ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *Image; + CHAR8 *PdbFileName; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + EFI_STRING StringPtr; + EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_GUID *NameGuid; + CHAR16 *NameString; + UINTN StringSize; + CHAR8 *PlatformLanguage; + CHAR8 *BestLanguage; + EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; + + Image = NULL; + LoadedImageDevicePath = NULL; + DevicePath = NULL; + + // + // Method 1: Get the name string from image PDB + // + 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)) { + Status = gBS->HandleProtocol ( + DriverBinding->ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&Image + ); + } + } + + if (!EFI_ERROR (Status)) { + PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); + + if (PdbFileName != NULL) { + DpGetShortPdbFileName (PdbFileName, mGaugeString); + return; + } + } + + // + // Method 2: Get the name string from ComponentName2 protocol + // + Status = gBS->HandleProtocol ( + Handle, + &gEfiComponentName2ProtocolGuid, + (VOID **)&ComponentName2 + ); + if (!EFI_ERROR (Status)) { + // + // Firstly use platform language setting, secondly use driver's first supported language. + // + GetVariable2 (L"PlatformLang", &gEfiGlobalVariableGuid, (VOID **)&PlatformLanguage, NULL); + BestLanguage = GetBestLanguage ( + ComponentName2->SupportedLanguages, + FALSE, + (PlatformLanguage != NULL) ? PlatformLanguage : "", + ComponentName2->SupportedLanguages, + NULL + ); + SHELL_FREE_NON_NULL (PlatformLanguage); + + Status = ComponentName2->GetDriverName ( + ComponentName2, + BestLanguage != NULL ? BestLanguage : "en-US", + &StringPtr + ); + if (!EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (BestLanguage); + StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); + mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; + return; + } + } + + Status = gBS->HandleProtocol ( + Handle, + &gEfiLoadedImageDevicePathProtocolGuid, + (VOID **)&LoadedImageDevicePath + ); + if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) { + DevicePath = LoadedImageDevicePath; + } else if (Image != NULL) { + DevicePath = Image->FilePath; + } + + if (DevicePath != NULL) { + // + // Try to get image GUID from image DevicePath + // + NameGuid = NULL; + while (!IsDevicePathEndType (DevicePath)) { + NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevicePath); + if (NameGuid != NULL) { + break; + } + + DevicePath = NextDevicePathNode (DevicePath); + } + + if (NameGuid != NULL) { + // + // Try to get the image's FFS UI section by image GUID + // + NameString = NULL; + StringSize = 0; + Status = GetSectionFromAnyFv ( + NameGuid, + EFI_SECTION_USER_INTERFACE, + 0, + (VOID **)&NameString, + &StringSize + ); + + if (!EFI_ERROR (Status)) { + // + // Method 3. Get the name string from FFS UI section + // + StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); + mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; + FreePool (NameString); + } else { + // + // Method 4: Get the name string from image GUID + // + UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid); + } + + return; + } else { + // + // Method 5: Get the name string from image DevicePath + // + NameString = ConvertDevicePathToText (DevicePath, TRUE, FALSE); + if (NameString != NULL) { + StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); + mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; + FreePool (NameString); + return; + } + } + } + + // + // Method 6: Unknown Driver Name + // + StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL); + ASSERT (StringPtr != NULL); + StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); + FreePool (StringPtr); +} + +/** + Calculate the Duration in microseconds. + + Duration is multiplied by 1000, instead of Frequency being divided by 1000 or + multiplying the result by 1000, in order to maintain precision. Since Duration is + a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow. + + The time is calculated as (Duration * 1000) / Timer_Frequency. + + @param[in] Duration The event duration in timer ticks. + + @return A 64-bit value which is the Elapsed time in microseconds. +**/ +UINT64 +DurationInMicroSeconds ( + IN UINT64 Duration + ) +{ + return DivU64x32 (Duration, 1000); +} + +/** + Get index of Measurement Record's match in the CumData array. + + If the Measurement's Token value matches a Token in one of the CumData + records, the index of the matching record is returned. The returned + index is a signed value so that negative values can indicate that + the Measurement didn't match any entry in the CumData array. + + @param[in] Measurement A pointer to a Measurement Record to match against the CumData array. + + @retval <0 Token is not in the CumData array. + @retval >=0 Return value is the index into CumData where Token is found. +**/ +INTN +GetCumulativeItem ( + IN MEASUREMENT_RECORD *Measurement + ) +{ + INTN Index; + + for ( Index = 0; Index < (INTN)NumCum; ++Index) { + if (AsciiStrCmp (Measurement->Token, CumData[Index].Name) == 0) { + return Index; // Exit, we found a match + } + } + + // If the for loop exits, Token was not found. + return -1; // Indicate failure +} diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.c index 4bb73af748..ff16771eb1 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.c @@ -1,22 +1,22 @@ -/** @file
- Definitions of ASCII string literals used by DP.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-#include <Guid/ExtendedFirmwarePerformance.h>
-
-// ASCII String literals which probably don't need translation
-CHAR8 const ALit_TimerLibError[] = "Timer library instance error!\n";
-CHAR8 const ALit_SEC[] = SEC_TOK;
-CHAR8 const ALit_DXE[] = DXE_TOK;
-CHAR8 const ALit_PEI[] = PEI_TOK;
-CHAR8 const ALit_BDS[] = BDS_TOK;
-CHAR8 const ALit_START_IMAGE[] = START_IMAGE_TOK;
-CHAR8 const ALit_LOAD_IMAGE[] = LOAD_IMAGE_TOK;
-CHAR8 const ALit_DB_START[] = DRIVERBINDING_START_TOK;
-CHAR8 const ALit_DB_SUPPORT[] = DRIVERBINDING_SUPPORT_TOK;
-CHAR8 const ALit_DB_STOP[] = DRIVERBINDING_STOP_TOK;
-
-CHAR8 const ALit_BdsTO[] = "BdsTimeOut";
-CHAR8 const ALit_PEIM[] = "PEIM";
+/** @file + Definitions of ASCII string literals used by DP. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Guid/ExtendedFirmwarePerformance.h> + +// ASCII String literals which probably don't need translation +CHAR8 const ALit_TimerLibError[] = "Timer library instance error!\n"; +CHAR8 const ALit_SEC[] = SEC_TOK; +CHAR8 const ALit_DXE[] = DXE_TOK; +CHAR8 const ALit_PEI[] = PEI_TOK; +CHAR8 const ALit_BDS[] = BDS_TOK; +CHAR8 const ALit_START_IMAGE[] = START_IMAGE_TOK; +CHAR8 const ALit_LOAD_IMAGE[] = LOAD_IMAGE_TOK; +CHAR8 const ALit_DB_START[] = DRIVERBINDING_START_TOK; +CHAR8 const ALit_DB_SUPPORT[] = DRIVERBINDING_SUPPORT_TOK; +CHAR8 const ALit_DB_STOP[] = DRIVERBINDING_STOP_TOK; + +CHAR8 const ALit_BdsTO[] = "BdsTimeOut"; +CHAR8 const ALit_PEIM[] = "PEIM"; diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.h b/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.h index 7174251ac4..53bd83a832 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Literals.h @@ -1,27 +1,27 @@ -/** @file
- Declarations of ASCII string literals used by DP.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef _LITERALS_H_
-#define _LITERALS_H_
-
-// ASCII String literals which probably don't need translation
-extern CHAR8 const ALit_TimerLibError[];
-extern CHAR8 const ALit_SEC[];
-extern CHAR8 const ALit_DXE[];
-extern CHAR8 const ALit_SHELL[];
-extern CHAR8 const ALit_PEI[];
-extern CHAR8 const ALit_BDS[];
-extern CHAR8 const ALit_PEIM[];
-extern CHAR8 const ALit_START_IMAGE[];
-extern CHAR8 const ALit_LOAD_IMAGE[];
-extern CHAR8 const ALit_DB_START[];
-extern CHAR8 const ALit_DB_SUPPORT[];
-extern CHAR8 const ALit_DB_STOP[];
-extern CHAR8 const ALit_BdsTO[];
-extern CHAR8 const ALit_PEIM[];
-
-#endif // _LITERALS_H_
+/** @file + Declarations of ASCII string literals used by DP. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _LITERALS_H_ +#define _LITERALS_H_ + +// ASCII String literals which probably don't need translation +extern CHAR8 const ALit_TimerLibError[]; +extern CHAR8 const ALit_SEC[]; +extern CHAR8 const ALit_DXE[]; +extern CHAR8 const ALit_SHELL[]; +extern CHAR8 const ALit_PEI[]; +extern CHAR8 const ALit_BDS[]; +extern CHAR8 const ALit_PEIM[]; +extern CHAR8 const ALit_START_IMAGE[]; +extern CHAR8 const ALit_LOAD_IMAGE[]; +extern CHAR8 const ALit_DB_START[]; +extern CHAR8 const ALit_DB_SUPPORT[]; +extern CHAR8 const ALit_DB_STOP[]; +extern CHAR8 const ALit_BdsTO[]; +extern CHAR8 const ALit_PEIM[]; + +#endif // _LITERALS_H_ diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c index b4e88e7635..6c058198cb 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c @@ -1,1904 +1,1904 @@ -/** @file
- The implementation for the 'http' Shell command.
-
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
- (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
- Copyright (c) 2020, Broadcom. All rights reserved. <BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include "Http.h"
-
-#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
-
-//
-// Constant strings and definitions related to the message
-// indicating the amount of progress in the dowloading of a HTTP file.
-//
-
-//
-// Number of steps in the progression slider.
-//
-#define HTTP_PROGRESS_SLIDER_STEPS \
- ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 3)
-
-//
-// Size in number of characters plus one (final zero) of the message to
-// indicate the progress of an HTTP download. The format is "[(progress slider:
-// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
-// are thus the number of characters in HTTP_PROGR_FRAME[] plus 11 characters
-// (2 // spaces, "Kb" and seven characters for the number of KBytes).
-//
-#define HTTP_PROGRESS_MESSAGE_SIZE \
- ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) + 12)
-
-//
-// Buffer size. Note that larger buffer does not mean better speed.
-//
-#define DEFAULT_BUF_SIZE SIZE_32KB
-#define MAX_BUF_SIZE SIZE_4MB
-
-#define MIN_PARAM_COUNT 2
-#define MAX_PARAM_COUNT 4
-#define NEED_REDIRECTION(Code) \
- (((Code >= HTTP_STATUS_300_MULTIPLE_CHOICES) \
- && (Code <= HTTP_STATUS_307_TEMPORARY_REDIRECT)) \
- || (Code == HTTP_STATUS_308_PERMANENT_REDIRECT))
-
-#define CLOSE_HTTP_HANDLE(ControllerHandle, HttpChildHandle) \
- do { \
- if (HttpChildHandle) { \
- CloseProtocolAndDestroyServiceChild ( \
- ControllerHandle, \
- &gEfiHttpServiceBindingProtocolGuid, \
- &gEfiHttpProtocolGuid, \
- HttpChildHandle \
- ); \
- HttpChildHandle = NULL; \
- } \
- } while (0)
-
-typedef enum {
- HdrHost,
- HdrConn,
- HdrAgent,
- HdrMax
-} HDR_TYPE;
-
-#define USER_AGENT_HDR "Mozilla/5.0 (EDK2; Linux) Gecko/20100101 Firefox/79.0"
-
-#define TIMER_MAX_TIMEOUT_S 10
-
-//
-// File name to use when Uri ends with "/".
-//
-#define DEFAULT_HTML_FILE L"index.html"
-#define DEFAULT_HTTP_PROTO L"http"
-
-//
-// String to delete the HTTP progress message to be able to update it :
-// (HTTP_PROGRESS_MESSAGE_SIZE-1) '\b'.
-//
-#define HTTP_PROGRESS_DEL \
- L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\
-\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
-
-#define HTTP_KB L"\b\b\b\b\b\b\b\b\b\b"
-//
-// Frame for the progression slider.
-//
-#define HTTP_PROGR_FRAME L"[ ]"
-
-//
-// Improve readability by using these macros.
-//
-#define PRINT_HII(token, ...) \
- ShellPrintHiiEx (\
- -1, -1, NULL, token, mHttpHiiHandle, __VA_ARGS__)
-
-#define PRINT_HII_APP(token, value) \
- PRINT_HII (token, HTTP_APP_NAME, value)
-
-//
-// TimeBaseLib.h constants.
-// These will be removed once the library gets fixed.
-//
-
-//
-// Define EPOCH (1970-JANUARY-01) in the Julian Date representation.
-//
-#define EPOCH_JULIAN_DATE 2440588
-
-//
-// Seconds per unit.
-//
-#define SEC_PER_MIN ((UINTN) 60)
-#define SEC_PER_HOUR ((UINTN) 3600)
-#define SEC_PER_DAY ((UINTN) 86400)
-
-//
-// String descriptions for server errors.
-//
-STATIC CONST CHAR16 *ErrStatusDesc[] =
-{
- L"400 Bad Request",
- L"401 Unauthorized",
- L"402 Payment required",
- L"403 Forbidden",
- L"404 Not Found",
- L"405 Method not allowed",
- L"406 Not acceptable",
- L"407 Proxy authentication required",
- L"408 Request time out",
- L"409 Conflict",
- L"410 Gone",
- L"411 Length required",
- L"412 Precondition failed",
- L"413 Request entity too large",
- L"414 Request URI to large",
- L"415 Unsupported media type",
- L"416 Requested range not satisfied",
- L"417 Expectation failed",
- L"500 Internal server error",
- L"501 Not implemented",
- L"502 Bad gateway",
- L"503 Service unavailable",
- L"504 Gateway timeout",
- L"505 HTTP version not supported"
-};
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-i", TypeValue },
- { L"-k", TypeFlag },
- { L"-l", TypeValue },
- { L"-m", TypeFlag },
- { L"-s", TypeValue },
- { L"-t", TypeValue },
- { NULL, TypeMax }
-};
-
-//
-// Local File Handle.
-//
-STATIC SHELL_FILE_HANDLE mFileHandle = NULL;
-
-//
-// Path of the local file, Unicode encoded.
-//
-STATIC CONST CHAR16 *mLocalFilePath;
-
-STATIC BOOLEAN gRequestCallbackComplete = FALSE;
-STATIC BOOLEAN gResponseCallbackComplete = FALSE;
-
-STATIC BOOLEAN gHttpError;
-
-EFI_HII_HANDLE mHttpHiiHandle;
-
-//
-// Functions declarations.
-//
-
-/**
- Check and convert the UINT16 option values of the 'http' command.
-
- @param[in] ValueStr Value as an Unicode encoded string.
- @param[out] Value UINT16 value.
-
- @retval TRUE The value was returned.
- @retval FALSE A parsing error occured.
-**/
-STATIC
-BOOLEAN
-StringToUint16 (
- IN CONST CHAR16 *ValueStr,
- OUT UINT16 *Value
- );
-
-/**
- Get the name of the NIC.
-
- @param[in] ControllerHandle The network physical device handle.
- @param[in] NicNumber The network physical device number.
- @param[out] NicName Address where to store the NIC name.
- The memory area has to be at least
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
- double byte wide.
-
- @retval EFI_SUCCESS The name of the NIC was returned.
- @retval Others The creation of the child for the Managed
- Network Service failed or the opening of
- the Managed Network Protocol failed or
- the operational parameters for the
- Managed Network Protocol could not be
- read.
-**/
-STATIC
-EFI_STATUS
-GetNicName (
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NicNumber,
- OUT CHAR16 *NicName
- );
-
-/**
- Create a child for the service identified by its service binding protocol GUID
- and get from the child the interface of the protocol identified by its GUID.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be created.
- @param[in] ProtocolGuid GUID of the protocol to be open.
- @param[out] ChildHandle Address where the handler of the
- created child is returned. NULL is
- returned in case of error.
- @param[out] Interface Address where a pointer to the
- protocol interface is returned in
- case of success.
-
- @retval EFI_SUCCESS The child was created and the protocol opened.
- @retval Others Either the creation of the child or the opening
- of the protocol failed.
-**/
-STATIC
-EFI_STATUS
-CreateServiceChildAndOpenProtocol (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- OUT EFI_HANDLE *ChildHandle,
- OUT VOID **Interface
- );
-
-/**
- Close the protocol identified by its GUID on the child handle of the service
- identified by its service binding protocol GUID, then destroy the child
- handle.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be destroyed.
- @param[in] ProtocolGuid GUID of the protocol to be closed.
- @param[in] ChildHandle Handle of the child to be destroyed.
-
-**/
-STATIC
-VOID
-CloseProtocolAndDestroyServiceChild (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- IN EFI_HANDLE ChildHandle
- );
-
-/**
- Worker function that download the data of a file from an HTTP server given
- the path of the file and its size.
-
- @param[in] Context A pointer to the download context.
-
- @retval EFI_SUCCESS The file was downloaded.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval Others The downloading of the file
- from the server failed.
-**/
-STATIC
-EFI_STATUS
-DownloadFile (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN EFI_HANDLE ControllerHandle,
- IN CHAR16 *NicName
- );
-
-/**
- Cleans off leading and trailing spaces and tabs.
-
- @param[in] String pointer to the string to trim them off.
-
- @retval EFI_SUCCESS No errors.
- @retval EFI_INVALID_PARAMETER String pointer is NULL.
-**/
-STATIC
-EFI_STATUS
-TrimSpaces (
- IN CHAR16 *String
- )
-{
- CHAR16 *Str;
- UINTN Len;
-
- ASSERT (String != NULL);
-
- if (String == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Str = String;
-
- //
- // Remove any whitespace at the beginning of the Str.
- //
- while (*Str == L' ' || *Str == L'\t') {
- Str++;
- }
-
- //
- // Remove any whitespace at the end of the Str.
- //
- do {
- Len = StrLen (Str);
- if (!Len || ((Str[Len - 1] != L' ') && (Str[Len - 1] != '\t'))) {
- break;
- }
-
- Str[Len - 1] = CHAR_NULL;
- } while (Len);
-
- CopyMem (String, Str, StrSize (Str));
-
- return EFI_SUCCESS;
-}
-
-//
-// Callbacks for request and response.
-// We just acknowledge that operation has completed here.
-//
-
-/**
- Callback to set the request completion flag.
-
- @param[in] Event: The event.
- @param[in] Context: pointer to Notification Context.
- **/
-STATIC
-VOID
-EFIAPI
-RequestCallback (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- gRequestCallbackComplete = TRUE;
-}
-
-/**
- Callback to set the response completion flag.
- @param[in] Event: The event.
- @param[in] Context: pointer to Notification Context.
- **/
-STATIC
-VOID
-EFIAPI
-ResponseCallback (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- gResponseCallbackComplete = TRUE;
-}
-
-//
-// Set of functions from TimeBaseLib.
-// This will be removed once TimeBaseLib is enabled for ShellPkg.
-//
-
-/**
- Calculate Epoch days.
-
- @param[in] Time - a pointer to the EFI_TIME abstraction.
-
- @retval Number of days elapsed since EPOCH_JULIAN_DAY.
- **/
-STATIC
-UINTN
-EfiGetEpochDays (
- IN EFI_TIME *Time
- )
-{
- UINTN a;
- UINTN y;
- UINTN m;
- //
- // Absolute Julian Date representation of the supplied Time.
- //
- UINTN JulianDate;
- //
- // Number of days elapsed since EPOCH_JULIAN_DAY.
- //
- UINTN EpochDays;
-
- a = (14 - Time->Month) / 12;
- y = Time->Year + 4800 - a;
- m = Time->Month + (12 * a) - 3;
-
- JulianDate = Time->Day + ((153 * m + 2) / 5) + (365 * y) + (y / 4) -
- (y / 100) + (y / 400) - 32045;
-
- ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
- EpochDays = JulianDate - EPOCH_JULIAN_DATE;
-
- return EpochDays;
-}
-
-/**
- Converts EFI_TIME to Epoch seconds
- (elapsed since 1970 JANUARY 01, 00:00:00 UTC).
-
- @param[in] Time: a pointer to EFI_TIME abstraction.
- **/
-STATIC
-UINTN
-EFIAPI
-EfiTimeToEpoch (
- IN EFI_TIME *Time
- )
-{
- //
- // Number of days elapsed since EPOCH_JULIAN_DAY.
- //
- UINTN EpochDays;
- UINTN EpochSeconds;
-
- EpochDays = EfiGetEpochDays (Time);
-
- EpochSeconds = (EpochDays * SEC_PER_DAY) +
- ((UINTN)Time->Hour * SEC_PER_HOUR) +
- (Time->Minute * SEC_PER_MIN) + Time->Second;
-
- return EpochSeconds;
-}
-
-/**
- Function for 'http' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The 'http' command completed successfully.
- @retval SHELL_ABORTED The Shell Library initialization failed.
- @retval SHELL_INVALID_PARAMETER At least one of the command's arguments is
- not valid.
- @retval SHELL_OUT_OF_RESOURCES A memory allocation failed.
- @retval SHELL_NOT_FOUND Network Interface Card not found.
- @retval SHELL_UNSUPPORTED Command was valid, but the server returned
- a status code indicating some error.
- Examine the file requested for error body.
-**/
-SHELL_STATUS
-RunHttp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- UINTN ParamCount;
- UINTN HandleCount;
- UINTN NicNumber;
- UINTN InitialSize;
- UINTN ParamOffset;
- UINTN StartSize;
- CHAR16 *ProblemParam;
- CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];
- CHAR16 *Walker1;
- CHAR16 *VStr;
- CONST CHAR16 *UserNicName;
- CONST CHAR16 *ValueStr;
- CONST CHAR16 *RemoteFilePath;
- CONST CHAR16 *Walker;
- EFI_HTTPv4_ACCESS_POINT IPv4Node;
- EFI_HANDLE *Handles;
- EFI_HANDLE ControllerHandle;
- HTTP_DOWNLOAD_CONTEXT Context;
- BOOLEAN NicFound;
-
- ProblemParam = NULL;
- RemoteFilePath = NULL;
- NicFound = FALSE;
- Handles = NULL;
-
- //
- // Initialize the Shell library (we must be in non-auto-init...).
- //
- ParamOffset = 0;
- gHttpError = FALSE;
-
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
-
- ZeroMem (&Context, sizeof (Context));
-
- //
- // Parse the command line.
- //
- Status = ShellCommandLineParse (
- ParamList,
- &CheckPackage,
- &ProblemParam,
- TRUE
- );
- if (EFI_ERROR (Status)) {
- if ( (Status == EFI_VOLUME_CORRUPTED)
- && (ProblemParam != NULL))
- {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_PROBLEM), ProblemParam);
- SHELL_FREE_NON_NULL (ProblemParam);
- } else {
- ASSERT (FALSE);
- }
-
- goto Error;
- }
-
- //
- // Check the number of parameters.
- //
- Status = EFI_INVALID_PARAMETER;
-
- ParamCount = ShellCommandLineGetCount (CheckPackage);
- if (ParamCount > MAX_PARAM_COUNT) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_MANY), NULL);
- goto Error;
- }
-
- if (ParamCount < MIN_PARAM_COUNT) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_FEW), NULL);
- goto Error;
- }
-
- ZeroMem (&Context.HttpConfigData, sizeof (Context.HttpConfigData));
- ZeroMem (&IPv4Node, sizeof (IPv4Node));
- IPv4Node.UseDefaultAddress = TRUE;
-
- Context.HttpConfigData.HttpVersion = HttpVersion11;
- Context.HttpConfigData.AccessPoint.IPv4Node = &IPv4Node;
-
- //
- // Get the host address (not necessarily IPv4 format).
- //
- ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (!ValueStr) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
- goto Error;
- } else {
- StartSize = 0;
- TrimSpaces ((CHAR16 *)ValueStr);
- if (!StrStr (ValueStr, L"://")) {
- Context.ServerAddrAndProto = StrnCatGrow (
- &Context.ServerAddrAndProto,
- &StartSize,
- DEFAULT_HTTP_PROTO,
- StrLen (DEFAULT_HTTP_PROTO)
- );
- Context.ServerAddrAndProto = StrnCatGrow (
- &Context.ServerAddrAndProto,
- &StartSize,
- L"://",
- StrLen (L"://")
- );
- VStr = (CHAR16 *)ValueStr;
- } else {
- VStr = StrStr (ValueStr, L"://") + StrLen (L"://");
- }
-
- for (Walker1 = VStr; *Walker1; Walker1++) {
- if (*Walker1 == L'/') {
- break;
- }
- }
-
- if (*Walker1 == L'/') {
- ParamOffset = 1;
- RemoteFilePath = Walker1;
- }
-
- Context.ServerAddrAndProto = StrnCatGrow (
- &Context.ServerAddrAndProto,
- &StartSize,
- ValueStr,
- StrLen (ValueStr) - StrLen (Walker1)
- );
- if (!Context.ServerAddrAndProto) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
- }
-
- if (!RemoteFilePath) {
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- if (!RemoteFilePath) {
- //
- // If no path given, assume just "/".
- //
- RemoteFilePath = L"/";
- }
- }
-
- TrimSpaces ((CHAR16 *)RemoteFilePath);
-
- if (ParamCount == MAX_PARAM_COUNT - ParamOffset) {
- mLocalFilePath = ShellCommandLineGetRawValue (
- CheckPackage,
- MAX_PARAM_COUNT - 1 - ParamOffset
- );
- } else {
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\\') ||
- (*Walker == L'/'))
- {
- break;
- }
- }
-
- mLocalFilePath = Walker + 1;
- }
-
- if (!StrLen (mLocalFilePath)) {
- mLocalFilePath = DEFAULT_HTML_FILE;
- }
-
- InitialSize = 0;
- Context.Uri = StrnCatGrow (
- &Context.Uri,
- &InitialSize,
- RemoteFilePath,
- StrLen (RemoteFilePath)
- );
- if (!Context.Uri) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- //
- // Get the name of the Network Interface Card to be used if any.
- //
- UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");
- if ( (ValueStr != NULL)
- && (!StringToUint16 (
- ValueStr,
- &Context.HttpConfigData.AccessPoint.IPv4Node->LocalPort
- )
- ))
- {
- goto Error;
- }
-
- Context.BufferSize = DEFAULT_BUF_SIZE;
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");
- if (ValueStr != NULL) {
- Context.BufferSize = ShellStrToUintn (ValueStr);
- if (!Context.BufferSize || (Context.BufferSize > MAX_BUF_SIZE)) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
- goto Error;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
- if (ValueStr != NULL) {
- Context.HttpConfigData.TimeOutMillisec = (UINT32)ShellStrToUintn (ValueStr);
- }
-
- //
- // Locate all HTTP Service Binding protocols.
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- if (EFI_ERROR (Status) || (HandleCount == 0)) {
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NO_NIC), NULL);
- if (!EFI_ERROR (Status)) {
- Status = EFI_NOT_FOUND;
- }
-
- goto Error;
- }
-
- Status = EFI_NOT_FOUND;
-
- Context.Flags = 0;
- if (ShellCommandLineGetFlag (CheckPackage, L"-m")) {
- Context.Flags |= DL_FLAG_TIME;
- }
-
- if (ShellCommandLineGetFlag (CheckPackage, L"-k")) {
- Context.Flags |= DL_FLAG_KEEP_BAD;
- }
-
- for (NicNumber = 0;
- (NicNumber < HandleCount) && (Status != EFI_SUCCESS);
- NicNumber++)
- {
- ControllerHandle = Handles[NicNumber];
-
- Status = GetNicName (ControllerHandle, NicNumber, NicName);
- if (EFI_ERROR (Status)) {
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NAME), NicNumber, Status);
- continue;
- }
-
- if (UserNicName != NULL) {
- if (StrCmp (NicName, UserNicName) != 0) {
- Status = EFI_NOT_FOUND;
- continue;
- }
-
- NicFound = TRUE;
- }
-
- Status = DownloadFile (&Context, ControllerHandle, NicName);
- PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);
-
- if (EFI_ERROR (Status)) {
- PRINT_HII (
- STRING_TOKEN (STR_HTTP_ERR_DOWNLOAD),
- RemoteFilePath,
- NicName,
- Status
- );
- //
- // If a user aborted the operation,
- // do not try another controller.
- //
- if (Status == EFI_ABORTED) {
- goto Error;
- }
- }
-
- if (gHttpError) {
- //
- // This is not related to connection, so no need to repeat with
- // another interface.
- //
- break;
- }
- }
-
- if ((UserNicName != NULL) && (!NicFound)) {
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NOT_FOUND), UserNicName);
- }
-
-Error:
- ShellCommandLineFreeVarList (CheckPackage);
- SHELL_FREE_NON_NULL (Handles);
- SHELL_FREE_NON_NULL (Context.ServerAddrAndProto);
- SHELL_FREE_NON_NULL (Context.Uri);
-
- return Status & ~MAX_BIT;
-}
-
-/**
- Check and convert the UINT16 option values of the 'http' command
-
- @param[in] ValueStr Value as an Unicode encoded string
- @param[out] Value UINT16 value
-
- @retval TRUE The value was returned.
- @retval FALSE A parsing error occured.
-**/
-STATIC
-BOOLEAN
-StringToUint16 (
- IN CONST CHAR16 *ValueStr,
- OUT UINT16 *Value
- )
-{
- UINTN Val;
-
- Val = ShellStrToUintn (ValueStr);
- if (Val > MAX_UINT16) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
- return FALSE;
- }
-
- *Value = (UINT16)Val;
- return TRUE;
-}
-
-/**
- Get the name of the NIC.
-
- @param[in] ControllerHandle The network physical device handle.
- @param[in] NicNumber The network physical device number.
- @param[out] NicName Address where to store the NIC name.
- The memory area has to be at least
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
- double byte wide.
-
- @retval EFI_SUCCESS The name of the NIC was returned.
- @retval Others The creation of the child for the Managed
- Network Service failed or the opening of
- the Managed Network Protocol failed or
- the operational parameters for the
- Managed Network Protocol could not be
- read.
-**/
-STATIC
-EFI_STATUS
-GetNicName (
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NicNumber,
- OUT CHAR16 *NicName
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE MnpHandle;
- EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
- EFI_SIMPLE_NETWORK_MODE SnpMode;
-
- Status = CreateServiceChildAndOpenProtocol (
- ControllerHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- &gEfiManagedNetworkProtocolGuid,
- &MnpHandle,
- (VOID **)&Mnp
- );
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
- if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
- goto Error;
- }
-
- UnicodeSPrint (
- NicName,
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
- SnpMode.IfType == NET_IFTYPE_ETHERNET ? L"eth%d" : L"unk%d",
- NicNumber
- );
-
- Status = EFI_SUCCESS;
-
-Error:
-
- if (MnpHandle != NULL) {
- CloseProtocolAndDestroyServiceChild (
- ControllerHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- &gEfiManagedNetworkProtocolGuid,
- MnpHandle
- );
- }
-
- return Status;
-}
-
-/**
- Create a child for the service identified by its service binding protocol GUID
- and get from the child the interface of the protocol identified by its GUID.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be created.
- @param[in] ProtocolGuid GUID of the protocol to be open.
- @param[out] ChildHandle Address where the handler of the
- created child is returned. NULL is
- returned in case of error.
- @param[out] Interface Address where a pointer to the
- protocol interface is returned in
- case of success.
-
- @retval EFI_SUCCESS The child was created and the protocol opened.
- @retval Others Either the creation of the child or the opening
- of the protocol failed.
-**/
-STATIC
-EFI_STATUS
-CreateServiceChildAndOpenProtocol (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- OUT EFI_HANDLE *ChildHandle,
- OUT VOID **Interface
- )
-{
- EFI_STATUS Status;
-
- *ChildHandle = NULL;
- Status = NetLibCreateServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- ChildHandle
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- *ChildHandle,
- ProtocolGuid,
- Interface,
- gImageHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- NetLibDestroyServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- *ChildHandle
- );
- *ChildHandle = NULL;
- }
- }
-
- return Status;
-}
-
-/**
- Close the protocol identified by its GUID on the child handle of the service
- identified by its service binding protocol GUID, then destroy the child
- handle.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be destroyed.
- @param[in] ProtocolGuid GUID of the protocol to be closed.
- @param[in] ChildHandle Handle of the child to be destroyed.
-**/
-STATIC
-VOID
-CloseProtocolAndDestroyServiceChild (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- IN EFI_HANDLE ChildHandle
- )
-{
- gBS->CloseProtocol (
- ChildHandle,
- ProtocolGuid,
- gImageHandle,
- ControllerHandle
- );
-
- NetLibDestroyServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- ChildHandle
- );
-}
-
-/**
- Wait until operation completes. Completion is indicated by
- setting of an appropriate variable.
-
- @param[in] Context A pointer to the HTTP download context.
- @param[in, out] CallBackComplete A pointer to the callback completion
- variable set by the callback.
-
- @retval EFI_SUCCESS Callback signalled completion.
- @retval EFI_TIMEOUT Timed out waiting for completion.
- @retval Others Error waiting for completion.
-**/
-STATIC
-EFI_STATUS
-WaitForCompletion (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN OUT BOOLEAN *CallBackComplete
- )
-{
- EFI_STATUS Status;
- EFI_EVENT WaitEvt;
-
- Status = EFI_SUCCESS;
-
- //
- // Use a timer to measure timeout. Cannot use Stall here!
- //
- Status = gBS->CreateEvent (
- EVT_TIMER,
- TPL_CALLBACK,
- NULL,
- NULL,
- &WaitEvt
- );
- ASSERT_EFI_ERROR (Status);
-
- if (!EFI_ERROR (Status)) {
- Status = gBS->SetTimer (
- WaitEvt,
- TimerRelative,
- EFI_TIMER_PERIOD_SECONDS (TIMER_MAX_TIMEOUT_S)
- );
-
- ASSERT_EFI_ERROR (Status);
- }
-
- while ( !*CallBackComplete
- && (!EFI_ERROR (Status))
- && EFI_ERROR (gBS->CheckEvent (WaitEvt)))
- {
- Status = Context->Http->Poll (Context->Http);
- if ( !Context->ContentDownloaded
- && (CallBackComplete == &gResponseCallbackComplete))
- {
- //
- // An HTTP server may just send a response redirection header.
- // In this case, don't wait for the event as
- // it might never happen and we waste 10s waiting.
- // Note that at this point Response may not has been populated,
- // so it needs to be checked first.
- //
- if ( Context->ResponseToken.Message
- && Context->ResponseToken.Message->Data.Response
- && (NEED_REDIRECTION (
- Context->ResponseToken.Message->Data.Response->StatusCode
- )
- ))
- {
- break;
- }
- }
- }
-
- gBS->SetTimer (WaitEvt, TimerCancel, 0);
- gBS->CloseEvent (WaitEvt);
-
- if (*CallBackComplete) {
- return EFI_SUCCESS;
- }
-
- if (!EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- }
-
- return Status;
-}
-
-/**
- Generate and send a request to the http server.
-
- @param[in] Context HTTP download context.
- @param[in] DownloadUrl Fully qualified URL to be downloaded.
-
- @retval EFI_SUCCESS Request has been sent successfully.
- @retval EFI_INVALID_PARAMETER Invalid URL.
- @retval EFI_OUT_OF_RESOURCES Out of memory.
- @retval EFI_DEVICE_ERROR If HTTPS is used, this probably
- means that TLS support either was not
- installed or not configured.
- @retval Others Error sending the request.
-**/
-STATIC
-EFI_STATUS
-SendRequest (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN CHAR16 *DownloadUrl
- )
-{
- EFI_HTTP_REQUEST_DATA RequestData;
- EFI_HTTP_HEADER RequestHeader[HdrMax];
- EFI_HTTP_MESSAGE RequestMessage;
- EFI_STATUS Status;
- CHAR16 *Host;
- UINTN StringSize;
-
- ZeroMem (&RequestData, sizeof (RequestData));
- ZeroMem (&RequestHeader, sizeof (RequestHeader));
- ZeroMem (&RequestMessage, sizeof (RequestMessage));
- ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));
-
- RequestHeader[HdrHost].FieldName = "Host";
- RequestHeader[HdrConn].FieldName = "Connection";
- RequestHeader[HdrAgent].FieldName = "User-Agent";
-
- Host = (CHAR16 *)Context->ServerAddrAndProto;
- while (*Host != CHAR_NULL && *Host != L'/') {
- Host++;
- }
-
- if (*Host == CHAR_NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Get the next slash.
- //
- Host++;
- //
- // And now the host name.
- //
- Host++;
-
- StringSize = StrLen (Host) + 1;
- RequestHeader[HdrHost].FieldValue = AllocatePool (StringSize);
- if (!RequestHeader[HdrHost].FieldValue) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- UnicodeStrToAsciiStrS (
- Host,
- RequestHeader[HdrHost].FieldValue,
- StringSize
- );
-
- RequestHeader[HdrConn].FieldValue = "close";
- RequestHeader[HdrAgent].FieldValue = USER_AGENT_HDR;
- RequestMessage.HeaderCount = HdrMax;
-
- RequestData.Method = HttpMethodGet;
- RequestData.Url = DownloadUrl;
-
- RequestMessage.Data.Request = &RequestData;
- RequestMessage.Headers = RequestHeader;
- RequestMessage.BodyLength = 0;
- RequestMessage.Body = NULL;
- Context->RequestToken.Event = NULL;
-
- //
- // Completion callback event to be set when Request completes.
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- RequestCallback,
- Context,
- &Context->RequestToken.Event
- );
- ASSERT_EFI_ERROR (Status);
-
- Context->RequestToken.Status = EFI_SUCCESS;
- Context->RequestToken.Message = &RequestMessage;
- gRequestCallbackComplete = FALSE;
- Status = Context->Http->Request (Context->Http, &Context->RequestToken);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- Status = WaitForCompletion (Context, &gRequestCallbackComplete);
- if (EFI_ERROR (Status)) {
- Context->Http->Cancel (Context->Http, &Context->RequestToken);
- }
-
-Error:
- SHELL_FREE_NON_NULL (RequestHeader[HdrHost].FieldValue);
- if (Context->RequestToken.Event) {
- gBS->CloseEvent (Context->RequestToken.Event);
- ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));
- }
-
- return Status;
-}
-
-/**
- Update the progress of a file download
- This procedure is called each time a new HTTP body portion is received.
-
- @param[in] Context HTTP download context.
- @param[in] DownloadLen Portion size, in bytes.
- @param[in] Buffer The pointer to the parsed buffer.
-
- @retval EFI_SUCCESS Portion saved.
- @retval Other Error saving the portion.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-SavePortion (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN UINTN DownloadLen,
- IN CHAR8 *Buffer
- )
-{
- CHAR16 Progress[HTTP_PROGRESS_MESSAGE_SIZE];
- UINTN NbOfKb;
- UINTN Index;
- UINTN LastStep;
- UINTN Step;
- EFI_STATUS Status;
-
- LastStep = 0;
- Step = 0;
-
- ShellSetFilePosition (mFileHandle, Context->LastReportedNbOfBytes);
- Status = ShellWriteFile (mFileHandle, &DownloadLen, Buffer);
- if (EFI_ERROR (Status)) {
- if (Context->ContentDownloaded > 0) {
- PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);
- }
-
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_WRITE), mLocalFilePath, Status);
- return Status;
- }
-
- if (Context->ContentDownloaded == 0) {
- ShellPrintEx (-1, -1, L"%s 0 Kb", HTTP_PROGR_FRAME);
- }
-
- Context->ContentDownloaded += DownloadLen;
- NbOfKb = Context->ContentDownloaded >> 10;
-
- Progress[0] = L'\0';
- if (Context->ContentLength) {
- LastStep = (Context->LastReportedNbOfBytes * HTTP_PROGRESS_SLIDER_STEPS) /
- Context->ContentLength;
- Step = (Context->ContentDownloaded * HTTP_PROGRESS_SLIDER_STEPS) /
- Context->ContentLength;
- }
-
- Context->LastReportedNbOfBytes = Context->ContentDownloaded;
-
- if (Step <= LastStep) {
- if (!Context->ContentLength) {
- //
- // Update downloaded size, there is no length info available.
- //
- ShellPrintEx (-1, -1, L"%s", HTTP_KB);
- ShellPrintEx (-1, -1, L"%7d Kb", NbOfKb);
- }
-
- return EFI_SUCCESS;
- }
-
- ShellPrintEx (-1, -1, L"%s", HTTP_PROGRESS_DEL);
-
- Status = StrCpyS (Progress, HTTP_PROGRESS_MESSAGE_SIZE, HTTP_PROGR_FRAME);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 1; Index < Step; Index++) {
- Progress[Index] = L'=';
- }
-
- if (Step) {
- Progress[Step] = L'>';
- }
-
- UnicodeSPrint (
- Progress + (sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 1,
- sizeof (Progress) - sizeof (HTTP_PROGR_FRAME),
- L" %7d Kb",
- NbOfKb
- );
-
- ShellPrintEx (-1, -1, L"%s", Progress);
-
- return EFI_SUCCESS;
-}
-
-/**
- Replace the original Host and Uri with Host and Uri returned by the
- HTTP server in 'Location' header (redirection).
-
- @param[in] Location A pointer to the 'Location' string
- provided by HTTP server.
- @param[in] Context A pointer to HTTP download context.
- @param[in] DownloadUrl Fully qualified HTTP URL.
-
- @retval EFI_SUCCESS Host and Uri were successfully set.
- @retval EFI_OUT_OF_RESOURCES Error setting Host or Uri.
-**/
-STATIC
-EFI_STATUS
-SetHostURI (
- IN CHAR8 *Location,
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN CHAR16 *DownloadUrl
- )
-{
- EFI_STATUS Status;
- UINTN StringSize;
- UINTN FirstStep;
- UINTN Idx;
- UINTN Step;
- CHAR8 *Walker;
- CHAR16 *Temp;
- CHAR8 *Tmp;
- CHAR16 *Url;
- BOOLEAN IsAbEmptyUrl;
-
- Tmp = NULL;
- Url = NULL;
- IsAbEmptyUrl = FALSE;
- FirstStep = 0;
-
- StringSize = (AsciiStrSize (Location) * sizeof (CHAR16));
- Url = AllocateZeroPool (StringSize);
- if (!Url) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = AsciiStrToUnicodeStrS (
- (CONST CHAR8 *)Location,
- Url,
- StringSize
- );
-
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- //
- // If an HTTP server redirects to the same location more than once,
- // then stop attempts and tell it is not reachable.
- //
- if (!StrCmp (Url, DownloadUrl)) {
- Status = EFI_NO_MAPPING;
- goto Error;
- }
-
- if (AsciiStrLen (Location) > 2) {
- //
- // Some servers return 'Location: //server/resource'
- //
- IsAbEmptyUrl = (Location[0] == '/') && (Location[1] == '/');
- if (IsAbEmptyUrl) {
- //
- // Skip first "//"
- //
- Location += 2;
- FirstStep = 1;
- }
- }
-
- if (AsciiStrStr (Location, "://") || IsAbEmptyUrl) {
- Idx = 0;
- Walker = Location;
-
- for (Step = FirstStep; Step < 2; Step++) {
- for ( ; *Walker != '/' && *Walker != '\0'; Walker++) {
- Idx++;
- }
-
- if (!Step) {
- //
- // Skip "//"
- //
- Idx += 2;
- Walker += 2;
- }
- }
-
- Tmp = AllocateZeroPool (Idx + 1);
- if (!Tmp) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- CopyMem (Tmp, Location, Idx);
-
- //
- // Location now points to Uri
- //
- Location += Idx;
- StringSize = (Idx + 1) * sizeof (CHAR16);
-
- SHELL_FREE_NON_NULL (Context->ServerAddrAndProto);
-
- Temp = AllocateZeroPool (StringSize);
- if (!Temp) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- Status = AsciiStrToUnicodeStrS (
- (CONST CHAR8 *)Tmp,
- Temp,
- StringSize
- );
- if (EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (Temp);
- goto Error;
- }
-
- Idx = 0;
- if (IsAbEmptyUrl) {
- Context->ServerAddrAndProto = StrnCatGrow (
- &Context->ServerAddrAndProto,
- &Idx,
- L"http://",
- StrLen (L"http://")
- );
- }
-
- Context->ServerAddrAndProto = StrnCatGrow (
- &Context->ServerAddrAndProto,
- &Idx,
- Temp,
- StrLen (Temp)
- );
- SHELL_FREE_NON_NULL (Temp);
- if (!Context->ServerAddrAndProto) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
- }
-
- SHELL_FREE_NON_NULL (Context->Uri);
-
- StringSize = AsciiStrSize (Location) * sizeof (CHAR16);
- Context->Uri = AllocateZeroPool (StringSize);
- if (!Context->Uri) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- //
- // Now make changes to the Uri part.
- //
- Status = AsciiStrToUnicodeStrS (
- (CONST CHAR8 *)Location,
- Context->Uri,
- StringSize
- );
-Error:
- SHELL_FREE_NON_NULL (Tmp);
- SHELL_FREE_NON_NULL (Url);
-
- return Status;
-}
-
-/**
- Message parser callback.
- Save a portion of HTTP body.
-
- @param[in] EventType Type of event. Can be either
- OnComplete or OnData.
- @param[in] Data A pointer to the buffer with data.
- @param[in] Length Data length of this portion.
- @param[in] Context A pointer to the HTTP download context.
-
- @retval EFI_SUCCESS The portion was processed successfully.
- @retval Other Error returned by SavePortion.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-ParseMsg (
- IN HTTP_BODY_PARSE_EVENT EventType,
- IN CHAR8 *Data,
- IN UINTN Length,
- IN VOID *Context
- )
-{
- if ( (Data == NULL)
- || (EventType == BodyParseEventOnComplete)
- || (Context == NULL))
- {
- return EFI_SUCCESS;
- }
-
- return SavePortion (Context, Length, Data);
-}
-
-/**
- Get HTTP server response and collect the whole body as a file.
- Set appropriate status in Context (REQ_OK, REQ_REPEAT, REQ_ERROR).
- Note that even if HTTP server returns an error code, it might send
- the body as well. This body will be collected in the resultant file.
-
- @param[in] Context A pointer to the HTTP download context.
- @param[in] DownloadUrl A pointer to the fully qualified URL to download.
-
- @retval EFI_SUCCESS Valid file. Body successfully collected.
- @retval EFI_HTTP_ERROR Response is a valid HTTP response, but the
- HTTP server
- indicated an error (HTTP code >= 400).
- Response body MAY contain full
- HTTP server response.
- @retval Others Error getting the reponse from the HTTP server.
- Response body is not collected.
-**/
-STATIC
-EFI_STATUS
-GetResponse (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN CHAR16 *DownloadUrl
- )
-{
- EFI_HTTP_RESPONSE_DATA ResponseData;
- EFI_HTTP_MESSAGE ResponseMessage;
- EFI_HTTP_HEADER *Header;
- EFI_STATUS Status;
- VOID *MsgParser;
- EFI_TIME StartTime;
- EFI_TIME EndTime;
- CONST CHAR16 *Desc;
- UINTN ElapsedSeconds;
- BOOLEAN IsTrunked;
- BOOLEAN CanMeasureTime;
-
- ZeroMem (&ResponseData, sizeof (ResponseData));
- ZeroMem (&ResponseMessage, sizeof (ResponseMessage));
- ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
- IsTrunked = FALSE;
-
- ResponseMessage.Body = Context->Buffer;
- Context->ResponseToken.Status = EFI_SUCCESS;
- Context->ResponseToken.Message = &ResponseMessage;
- Context->ContentLength = 0;
- Context->Status = REQ_OK;
- Status = EFI_SUCCESS;
- MsgParser = NULL;
- ResponseData.StatusCode = HTTP_STATUS_UNSUPPORTED_STATUS;
- ResponseMessage.Data.Response = &ResponseData;
- Context->ResponseToken.Event = NULL;
- CanMeasureTime = FALSE;
- if (Context->Flags & DL_FLAG_TIME) {
- ZeroMem (&StartTime, sizeof (StartTime));
- CanMeasureTime = !EFI_ERROR (gRT->GetTime (&StartTime, NULL));
- }
-
- do {
- SHELL_FREE_NON_NULL (ResponseMessage.Headers);
- ResponseMessage.HeaderCount = 0;
- gResponseCallbackComplete = FALSE;
- ResponseMessage.BodyLength = Context->BufferSize;
-
- if (ShellGetExecutionBreakFlag ()) {
- Status = EFI_ABORTED;
- break;
- }
-
- if (!Context->ContentDownloaded && !Context->ResponseToken.Event) {
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- ResponseCallback,
- Context,
- &Context->ResponseToken.Event
- );
- ASSERT_EFI_ERROR (Status);
- } else {
- ResponseMessage.Data.Response = NULL;
- }
-
- if (EFI_ERROR (Status)) {
- break;
- }
-
- Status = Context->Http->Response (Context->Http, &Context->ResponseToken);
- if (EFI_ERROR (Status)) {
- break;
- }
-
- Status = WaitForCompletion (Context, &gResponseCallbackComplete);
- if (EFI_ERROR (Status) && ResponseMessage.HeaderCount) {
- Status = EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- Context->Http->Cancel (Context->Http, &Context->ResponseToken);
- break;
- }
-
- if (!Context->ContentDownloaded) {
- if (NEED_REDIRECTION (ResponseData.StatusCode)) {
- //
- // Need to repeat the request with new Location (server redirected).
- //
- Context->Status = REQ_NEED_REPEAT;
-
- Header = HttpFindHeader (
- ResponseMessage.HeaderCount,
- ResponseMessage.Headers,
- "Location"
- );
- if (Header) {
- Status = SetHostURI (Header->FieldValue, Context, DownloadUrl);
- if (Status == EFI_NO_MAPPING) {
- PRINT_HII (
- STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
- Context->ServerAddrAndProto,
- L"Recursive HTTP server relocation",
- Context->Uri
- );
- }
- } else {
- //
- // Bad reply from the server. Server must specify the location.
- // Indicate that resource was not found, and no body collected.
- //
- Status = EFI_NOT_FOUND;
- }
-
- Context->Http->Cancel (Context->Http, &Context->ResponseToken);
- break;
- }
-
- //
- // Init message-body parser by header information.
- //
- if (!MsgParser) {
- Status = HttpInitMsgParser (
- ResponseMessage.Data.Request->Method,
- ResponseData.StatusCode,
- ResponseMessage.HeaderCount,
- ResponseMessage.Headers,
- ParseMsg,
- Context,
- &MsgParser
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- }
-
- //
- // If it is a trunked message, rely on the parser.
- //
- Header = HttpFindHeader (
- ResponseMessage.HeaderCount,
- ResponseMessage.Headers,
- "Transfer-Encoding"
- );
- IsTrunked = (Header && !AsciiStrCmp (Header->FieldValue, "chunked"));
-
- HttpGetEntityLength (MsgParser, &Context->ContentLength);
-
- if ( (ResponseData.StatusCode >= HTTP_STATUS_400_BAD_REQUEST)
- && (ResponseData.StatusCode != HTTP_STATUS_308_PERMANENT_REDIRECT))
- {
- //
- // Server reported an error via Response code.
- // Collect the body if any.
- //
- if (!gHttpError) {
- gHttpError = TRUE;
-
- Desc = ErrStatusDesc[ResponseData.StatusCode -
- HTTP_STATUS_400_BAD_REQUEST];
- PRINT_HII (
- STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
- Context->ServerAddrAndProto,
- Desc,
- Context->Uri
- );
-
- //
- // This gives an RFC HTTP error.
- //
- Context->Status = ShellStrToUintn (Desc);
- Status = ENCODE_ERROR (Context->Status);
- }
- }
- }
-
- //
- // Do NOT try to parse an empty body.
- //
- if (ResponseMessage.BodyLength || IsTrunked) {
- Status = HttpParseMessageBody (
- MsgParser,
- ResponseMessage.BodyLength,
- ResponseMessage.Body
- );
- }
- } while ( !HttpIsMessageComplete (MsgParser)
- && !EFI_ERROR (Status)
- && ResponseMessage.BodyLength);
-
- if ( (Context->Status != REQ_NEED_REPEAT)
- && (Status == EFI_SUCCESS)
- && CanMeasureTime)
- {
- if (!EFI_ERROR (gRT->GetTime (&EndTime, NULL))) {
- ElapsedSeconds = EfiTimeToEpoch (&EndTime) - EfiTimeToEpoch (&StartTime);
- Print (
- L",%a%Lus\n",
- ElapsedSeconds ? " " : " < ",
- ElapsedSeconds > 1 ? (UINT64)ElapsedSeconds : 1
- );
- }
- }
-
- SHELL_FREE_NON_NULL (MsgParser);
- if (Context->ResponseToken.Event) {
- gBS->CloseEvent (Context->ResponseToken.Event);
- ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
- }
-
- return Status;
-}
-
-/**
- Worker function that downloads the data of a file from an HTTP server given
- the path of the file and its size.
-
- @param[in] Context A pointer to the HTTP download context.
- @param[in] ControllerHandle The handle of the network interface controller
- @param[in] NicName NIC name
-
- @retval EFI_SUCCESS The file was downloaded.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- #return EFI_HTTP_ERROR The server returned a valid HTTP error.
- Examine the mLocalFilePath file
- to get error body.
- @retval Others The downloading of the file from the server
- failed.
-**/
-STATIC
-EFI_STATUS
-DownloadFile (
- IN HTTP_DOWNLOAD_CONTEXT *Context,
- IN EFI_HANDLE ControllerHandle,
- IN CHAR16 *NicName
- )
-{
- EFI_STATUS Status;
- CHAR16 *DownloadUrl;
- UINTN UrlSize;
- EFI_HANDLE HttpChildHandle;
-
- ASSERT (Context);
- if (Context == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DownloadUrl = NULL;
- HttpChildHandle = NULL;
-
- Context->Buffer = AllocatePool (Context->BufferSize);
- if (Context->Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
-
- //
- // Open the file.
- //
- if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
- ShellDeleteFileByName (mLocalFilePath);
- }
-
- Status = ShellOpenFileByName (
- mLocalFilePath,
- &mFileHandle,
- EFI_FILE_MODE_CREATE |
- EFI_FILE_MODE_WRITE |
- EFI_FILE_MODE_READ,
- 0
- );
- if (EFI_ERROR (Status)) {
- PRINT_HII_APP (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), mLocalFilePath);
- goto ON_EXIT;
- }
-
- do {
- SHELL_FREE_NON_NULL (DownloadUrl);
-
- CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);
-
- Status = CreateServiceChildAndOpenProtocol (
- ControllerHandle,
- &gEfiHttpServiceBindingProtocolGuid,
- &gEfiHttpProtocolGuid,
- &HttpChildHandle,
- (VOID **)&Context->Http
- );
-
- if (EFI_ERROR (Status)) {
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_OPEN_PROTOCOL), NicName, Status);
- goto ON_EXIT;
- }
-
- Status = Context->Http->Configure (Context->Http, &Context->HttpConfigData);
- if (EFI_ERROR (Status)) {
- PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_CONFIGURE), NicName, Status);
- goto ON_EXIT;
- }
-
- UrlSize = 0;
- DownloadUrl = StrnCatGrow (
- &DownloadUrl,
- &UrlSize,
- Context->ServerAddrAndProto,
- StrLen (Context->ServerAddrAndProto)
- );
- if (Context->Uri[0] != L'/') {
- DownloadUrl = StrnCatGrow (
- &DownloadUrl,
- &UrlSize,
- L"/",
- StrLen (Context->ServerAddrAndProto)
- );
- }
-
- DownloadUrl = StrnCatGrow (
- &DownloadUrl,
- &UrlSize,
- Context->Uri,
- StrLen (Context->Uri)
- );
-
- PRINT_HII (STRING_TOKEN (STR_HTTP_DOWNLOADING), DownloadUrl);
-
- Status = SendRequest (Context, DownloadUrl);
- if (Status) {
- goto ON_EXIT;
- }
-
- Status = GetResponse (Context, DownloadUrl);
-
- if (Status) {
- goto ON_EXIT;
- }
- } while (Context->Status == REQ_NEED_REPEAT);
-
- if (Context->Status) {
- Status = ENCODE_ERROR (Context->Status);
- }
-
-ON_EXIT:
- //
- // Close the file.
- //
- if (mFileHandle != NULL) {
- if (EFI_ERROR (Status) && !(Context->Flags & DL_FLAG_KEEP_BAD)) {
- ShellDeleteFile (&mFileHandle);
- } else {
- ShellCloseFile (&mFileHandle);
- }
- }
-
- SHELL_FREE_NON_NULL (DownloadUrl);
- SHELL_FREE_NON_NULL (Context->Buffer);
-
- CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);
-
- return Status;
-}
-
-/**
- Retrive HII package list from ImageHandle and publish to HII database.
-
- @param[in] ImageHandle The image handle of the process.
-
- @retval HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Retrieve HII package list from ImageHandle.
- //
- Status = gBS->OpenProtocol (
- ImageHandle,
- &gEfiHiiPackageListProtocolGuid,
- (VOID **)&PackageList,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Publish HII package list to HII Database.
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageList,
- NULL,
- &HiiHandle
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return HiiHandle;
-}
+/** @file + The implementation for the 'http' Shell command. + + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2020, Broadcom. All rights reserved. <BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Http.h" + +#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32 + +// +// Constant strings and definitions related to the message +// indicating the amount of progress in the dowloading of a HTTP file. +// + +// +// Number of steps in the progression slider. +// +#define HTTP_PROGRESS_SLIDER_STEPS \ + ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 3) + +// +// Size in number of characters plus one (final zero) of the message to +// indicate the progress of an HTTP download. The format is "[(progress slider: +// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There +// are thus the number of characters in HTTP_PROGR_FRAME[] plus 11 characters +// (2 // spaces, "Kb" and seven characters for the number of KBytes). +// +#define HTTP_PROGRESS_MESSAGE_SIZE \ + ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) + 12) + +// +// Buffer size. Note that larger buffer does not mean better speed. +// +#define DEFAULT_BUF_SIZE SIZE_32KB +#define MAX_BUF_SIZE SIZE_4MB + +#define MIN_PARAM_COUNT 2 +#define MAX_PARAM_COUNT 4 +#define NEED_REDIRECTION(Code) \ + (((Code >= HTTP_STATUS_300_MULTIPLE_CHOICES) \ + && (Code <= HTTP_STATUS_307_TEMPORARY_REDIRECT)) \ + || (Code == HTTP_STATUS_308_PERMANENT_REDIRECT)) + +#define CLOSE_HTTP_HANDLE(ControllerHandle, HttpChildHandle) \ + do { \ + if (HttpChildHandle) { \ + CloseProtocolAndDestroyServiceChild ( \ + ControllerHandle, \ + &gEfiHttpServiceBindingProtocolGuid, \ + &gEfiHttpProtocolGuid, \ + HttpChildHandle \ + ); \ + HttpChildHandle = NULL; \ + } \ + } while (0) + +typedef enum { + HdrHost, + HdrConn, + HdrAgent, + HdrMax +} HDR_TYPE; + +#define USER_AGENT_HDR "Mozilla/5.0 (EDK2; Linux) Gecko/20100101 Firefox/79.0" + +#define TIMER_MAX_TIMEOUT_S 10 + +// +// File name to use when Uri ends with "/". +// +#define DEFAULT_HTML_FILE L"index.html" +#define DEFAULT_HTTP_PROTO L"http" + +// +// String to delete the HTTP progress message to be able to update it : +// (HTTP_PROGRESS_MESSAGE_SIZE-1) '\b'. +// +#define HTTP_PROGRESS_DEL \ + L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\ +\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" + +#define HTTP_KB L"\b\b\b\b\b\b\b\b\b\b" +// +// Frame for the progression slider. +// +#define HTTP_PROGR_FRAME L"[ ]" + +// +// Improve readability by using these macros. +// +#define PRINT_HII(token, ...) \ + ShellPrintHiiEx (\ + -1, -1, NULL, token, mHttpHiiHandle, __VA_ARGS__) + +#define PRINT_HII_APP(token, value) \ + PRINT_HII (token, HTTP_APP_NAME, value) + +// +// TimeBaseLib.h constants. +// These will be removed once the library gets fixed. +// + +// +// Define EPOCH (1970-JANUARY-01) in the Julian Date representation. +// +#define EPOCH_JULIAN_DATE 2440588 + +// +// Seconds per unit. +// +#define SEC_PER_MIN ((UINTN) 60) +#define SEC_PER_HOUR ((UINTN) 3600) +#define SEC_PER_DAY ((UINTN) 86400) + +// +// String descriptions for server errors. +// +STATIC CONST CHAR16 *ErrStatusDesc[] = +{ + L"400 Bad Request", + L"401 Unauthorized", + L"402 Payment required", + L"403 Forbidden", + L"404 Not Found", + L"405 Method not allowed", + L"406 Not acceptable", + L"407 Proxy authentication required", + L"408 Request time out", + L"409 Conflict", + L"410 Gone", + L"411 Length required", + L"412 Precondition failed", + L"413 Request entity too large", + L"414 Request URI to large", + L"415 Unsupported media type", + L"416 Requested range not satisfied", + L"417 Expectation failed", + L"500 Internal server error", + L"501 Not implemented", + L"502 Bad gateway", + L"503 Service unavailable", + L"504 Gateway timeout", + L"505 HTTP version not supported" +}; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-i", TypeValue }, + { L"-k", TypeFlag }, + { L"-l", TypeValue }, + { L"-m", TypeFlag }, + { L"-s", TypeValue }, + { L"-t", TypeValue }, + { NULL, TypeMax } +}; + +// +// Local File Handle. +// +STATIC SHELL_FILE_HANDLE mFileHandle = NULL; + +// +// Path of the local file, Unicode encoded. +// +STATIC CONST CHAR16 *mLocalFilePath; + +STATIC BOOLEAN gRequestCallbackComplete = FALSE; +STATIC BOOLEAN gResponseCallbackComplete = FALSE; + +STATIC BOOLEAN gHttpError; + +EFI_HII_HANDLE mHttpHiiHandle; + +// +// Functions declarations. +// + +/** + Check and convert the UINT16 option values of the 'http' command. + + @param[in] ValueStr Value as an Unicode encoded string. + @param[out] Value UINT16 value. + + @retval TRUE The value was returned. + @retval FALSE A parsing error occured. +**/ +STATIC +BOOLEAN +StringToUint16 ( + IN CONST CHAR16 *ValueStr, + OUT UINT16 *Value + ); + +/** + Get the name of the NIC. + + @param[in] ControllerHandle The network physical device handle. + @param[in] NicNumber The network physical device number. + @param[out] NicName Address where to store the NIC name. + The memory area has to be at least + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH + double byte wide. + + @retval EFI_SUCCESS The name of the NIC was returned. + @retval Others The creation of the child for the Managed + Network Service failed or the opening of + the Managed Network Protocol failed or + the operational parameters for the + Managed Network Protocol could not be + read. +**/ +STATIC +EFI_STATUS +GetNicName ( + IN EFI_HANDLE ControllerHandle, + IN UINTN NicNumber, + OUT CHAR16 *NicName + ); + +/** + Create a child for the service identified by its service binding protocol GUID + and get from the child the interface of the protocol identified by its GUID. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be created. + @param[in] ProtocolGuid GUID of the protocol to be open. + @param[out] ChildHandle Address where the handler of the + created child is returned. NULL is + returned in case of error. + @param[out] Interface Address where a pointer to the + protocol interface is returned in + case of success. + + @retval EFI_SUCCESS The child was created and the protocol opened. + @retval Others Either the creation of the child or the opening + of the protocol failed. +**/ +STATIC +EFI_STATUS +CreateServiceChildAndOpenProtocol ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + OUT EFI_HANDLE *ChildHandle, + OUT VOID **Interface + ); + +/** + Close the protocol identified by its GUID on the child handle of the service + identified by its service binding protocol GUID, then destroy the child + handle. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be destroyed. + @param[in] ProtocolGuid GUID of the protocol to be closed. + @param[in] ChildHandle Handle of the child to be destroyed. + +**/ +STATIC +VOID +CloseProtocolAndDestroyServiceChild ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + IN EFI_HANDLE ChildHandle + ); + +/** + Worker function that download the data of a file from an HTTP server given + the path of the file and its size. + + @param[in] Context A pointer to the download context. + + @retval EFI_SUCCESS The file was downloaded. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval Others The downloading of the file + from the server failed. +**/ +STATIC +EFI_STATUS +DownloadFile ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN EFI_HANDLE ControllerHandle, + IN CHAR16 *NicName + ); + +/** + Cleans off leading and trailing spaces and tabs. + + @param[in] String pointer to the string to trim them off. + + @retval EFI_SUCCESS No errors. + @retval EFI_INVALID_PARAMETER String pointer is NULL. +**/ +STATIC +EFI_STATUS +TrimSpaces ( + IN CHAR16 *String + ) +{ + CHAR16 *Str; + UINTN Len; + + ASSERT (String != NULL); + + if (String == NULL) { + return EFI_INVALID_PARAMETER; + } + + Str = String; + + // + // Remove any whitespace at the beginning of the Str. + // + while (*Str == L' ' || *Str == L'\t') { + Str++; + } + + // + // Remove any whitespace at the end of the Str. + // + do { + Len = StrLen (Str); + if (!Len || ((Str[Len - 1] != L' ') && (Str[Len - 1] != '\t'))) { + break; + } + + Str[Len - 1] = CHAR_NULL; + } while (Len); + + CopyMem (String, Str, StrSize (Str)); + + return EFI_SUCCESS; +} + +// +// Callbacks for request and response. +// We just acknowledge that operation has completed here. +// + +/** + Callback to set the request completion flag. + + @param[in] Event: The event. + @param[in] Context: pointer to Notification Context. + **/ +STATIC +VOID +EFIAPI +RequestCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRequestCallbackComplete = TRUE; +} + +/** + Callback to set the response completion flag. + @param[in] Event: The event. + @param[in] Context: pointer to Notification Context. + **/ +STATIC +VOID +EFIAPI +ResponseCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gResponseCallbackComplete = TRUE; +} + +// +// Set of functions from TimeBaseLib. +// This will be removed once TimeBaseLib is enabled for ShellPkg. +// + +/** + Calculate Epoch days. + + @param[in] Time - a pointer to the EFI_TIME abstraction. + + @retval Number of days elapsed since EPOCH_JULIAN_DAY. + **/ +STATIC +UINTN +EfiGetEpochDays ( + IN EFI_TIME *Time + ) +{ + UINTN a; + UINTN y; + UINTN m; + // + // Absolute Julian Date representation of the supplied Time. + // + UINTN JulianDate; + // + // Number of days elapsed since EPOCH_JULIAN_DAY. + // + UINTN EpochDays; + + a = (14 - Time->Month) / 12; + y = Time->Year + 4800 - a; + m = Time->Month + (12 * a) - 3; + + JulianDate = Time->Day + ((153 * m + 2) / 5) + (365 * y) + (y / 4) - + (y / 100) + (y / 400) - 32045; + + ASSERT (JulianDate >= EPOCH_JULIAN_DATE); + EpochDays = JulianDate - EPOCH_JULIAN_DATE; + + return EpochDays; +} + +/** + Converts EFI_TIME to Epoch seconds + (elapsed since 1970 JANUARY 01, 00:00:00 UTC). + + @param[in] Time: a pointer to EFI_TIME abstraction. + **/ +STATIC +UINTN +EFIAPI +EfiTimeToEpoch ( + IN EFI_TIME *Time + ) +{ + // + // Number of days elapsed since EPOCH_JULIAN_DAY. + // + UINTN EpochDays; + UINTN EpochSeconds; + + EpochDays = EfiGetEpochDays (Time); + + EpochSeconds = (EpochDays * SEC_PER_DAY) + + ((UINTN)Time->Hour * SEC_PER_HOUR) + + (Time->Minute * SEC_PER_MIN) + Time->Second; + + return EpochSeconds; +} + +/** + Function for 'http' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). + + @retval SHELL_SUCCESS The 'http' command completed successfully. + @retval SHELL_ABORTED The Shell Library initialization failed. + @retval SHELL_INVALID_PARAMETER At least one of the command's arguments is + not valid. + @retval SHELL_OUT_OF_RESOURCES A memory allocation failed. + @retval SHELL_NOT_FOUND Network Interface Card not found. + @retval SHELL_UNSUPPORTED Command was valid, but the server returned + a status code indicating some error. + Examine the file requested for error body. +**/ +SHELL_STATUS +RunHttp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *CheckPackage; + UINTN ParamCount; + UINTN HandleCount; + UINTN NicNumber; + UINTN InitialSize; + UINTN ParamOffset; + UINTN StartSize; + CHAR16 *ProblemParam; + CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; + CHAR16 *Walker1; + CHAR16 *VStr; + CONST CHAR16 *UserNicName; + CONST CHAR16 *ValueStr; + CONST CHAR16 *RemoteFilePath; + CONST CHAR16 *Walker; + EFI_HTTPv4_ACCESS_POINT IPv4Node; + EFI_HANDLE *Handles; + EFI_HANDLE ControllerHandle; + HTTP_DOWNLOAD_CONTEXT Context; + BOOLEAN NicFound; + + ProblemParam = NULL; + RemoteFilePath = NULL; + NicFound = FALSE; + Handles = NULL; + + // + // Initialize the Shell library (we must be in non-auto-init...). + // + ParamOffset = 0; + gHttpError = FALSE; + + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + ZeroMem (&Context, sizeof (Context)); + + // + // Parse the command line. + // + Status = ShellCommandLineParse ( + ParamList, + &CheckPackage, + &ProblemParam, + TRUE + ); + if (EFI_ERROR (Status)) { + if ( (Status == EFI_VOLUME_CORRUPTED) + && (ProblemParam != NULL)) + { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_PROBLEM), ProblemParam); + SHELL_FREE_NON_NULL (ProblemParam); + } else { + ASSERT (FALSE); + } + + goto Error; + } + + // + // Check the number of parameters. + // + Status = EFI_INVALID_PARAMETER; + + ParamCount = ShellCommandLineGetCount (CheckPackage); + if (ParamCount > MAX_PARAM_COUNT) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_MANY), NULL); + goto Error; + } + + if (ParamCount < MIN_PARAM_COUNT) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_FEW), NULL); + goto Error; + } + + ZeroMem (&Context.HttpConfigData, sizeof (Context.HttpConfigData)); + ZeroMem (&IPv4Node, sizeof (IPv4Node)); + IPv4Node.UseDefaultAddress = TRUE; + + Context.HttpConfigData.HttpVersion = HttpVersion11; + Context.HttpConfigData.AccessPoint.IPv4Node = &IPv4Node; + + // + // Get the host address (not necessarily IPv4 format). + // + ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); + if (!ValueStr) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr); + goto Error; + } else { + StartSize = 0; + TrimSpaces ((CHAR16 *)ValueStr); + if (!StrStr (ValueStr, L"://")) { + Context.ServerAddrAndProto = StrnCatGrow ( + &Context.ServerAddrAndProto, + &StartSize, + DEFAULT_HTTP_PROTO, + StrLen (DEFAULT_HTTP_PROTO) + ); + Context.ServerAddrAndProto = StrnCatGrow ( + &Context.ServerAddrAndProto, + &StartSize, + L"://", + StrLen (L"://") + ); + VStr = (CHAR16 *)ValueStr; + } else { + VStr = StrStr (ValueStr, L"://") + StrLen (L"://"); + } + + for (Walker1 = VStr; *Walker1; Walker1++) { + if (*Walker1 == L'/') { + break; + } + } + + if (*Walker1 == L'/') { + ParamOffset = 1; + RemoteFilePath = Walker1; + } + + Context.ServerAddrAndProto = StrnCatGrow ( + &Context.ServerAddrAndProto, + &StartSize, + ValueStr, + StrLen (ValueStr) - StrLen (Walker1) + ); + if (!Context.ServerAddrAndProto) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + } + + if (!RemoteFilePath) { + RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); + if (!RemoteFilePath) { + // + // If no path given, assume just "/". + // + RemoteFilePath = L"/"; + } + } + + TrimSpaces ((CHAR16 *)RemoteFilePath); + + if (ParamCount == MAX_PARAM_COUNT - ParamOffset) { + mLocalFilePath = ShellCommandLineGetRawValue ( + CheckPackage, + MAX_PARAM_COUNT - 1 - ParamOffset + ); + } else { + Walker = RemoteFilePath + StrLen (RemoteFilePath); + while ((--Walker) >= RemoteFilePath) { + if ((*Walker == L'\\') || + (*Walker == L'/')) + { + break; + } + } + + mLocalFilePath = Walker + 1; + } + + if (!StrLen (mLocalFilePath)) { + mLocalFilePath = DEFAULT_HTML_FILE; + } + + InitialSize = 0; + Context.Uri = StrnCatGrow ( + &Context.Uri, + &InitialSize, + RemoteFilePath, + StrLen (RemoteFilePath) + ); + if (!Context.Uri) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Get the name of the Network Interface Card to be used if any. + // + UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i"); + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); + if ( (ValueStr != NULL) + && (!StringToUint16 ( + ValueStr, + &Context.HttpConfigData.AccessPoint.IPv4Node->LocalPort + ) + )) + { + goto Error; + } + + Context.BufferSize = DEFAULT_BUF_SIZE; + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s"); + if (ValueStr != NULL) { + Context.BufferSize = ShellStrToUintn (ValueStr); + if (!Context.BufferSize || (Context.BufferSize > MAX_BUF_SIZE)) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr); + goto Error; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); + if (ValueStr != NULL) { + Context.HttpConfigData.TimeOutMillisec = (UINT32)ShellStrToUintn (ValueStr); + } + + // + // Locate all HTTP Service Binding protocols. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiManagedNetworkServiceBindingProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + if (EFI_ERROR (Status) || (HandleCount == 0)) { + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NO_NIC), NULL); + if (!EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + } + + goto Error; + } + + Status = EFI_NOT_FOUND; + + Context.Flags = 0; + if (ShellCommandLineGetFlag (CheckPackage, L"-m")) { + Context.Flags |= DL_FLAG_TIME; + } + + if (ShellCommandLineGetFlag (CheckPackage, L"-k")) { + Context.Flags |= DL_FLAG_KEEP_BAD; + } + + for (NicNumber = 0; + (NicNumber < HandleCount) && (Status != EFI_SUCCESS); + NicNumber++) + { + ControllerHandle = Handles[NicNumber]; + + Status = GetNicName (ControllerHandle, NicNumber, NicName); + if (EFI_ERROR (Status)) { + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NAME), NicNumber, Status); + continue; + } + + if (UserNicName != NULL) { + if (StrCmp (NicName, UserNicName) != 0) { + Status = EFI_NOT_FOUND; + continue; + } + + NicFound = TRUE; + } + + Status = DownloadFile (&Context, ControllerHandle, NicName); + PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL); + + if (EFI_ERROR (Status)) { + PRINT_HII ( + STRING_TOKEN (STR_HTTP_ERR_DOWNLOAD), + RemoteFilePath, + NicName, + Status + ); + // + // If a user aborted the operation, + // do not try another controller. + // + if (Status == EFI_ABORTED) { + goto Error; + } + } + + if (gHttpError) { + // + // This is not related to connection, so no need to repeat with + // another interface. + // + break; + } + } + + if ((UserNicName != NULL) && (!NicFound)) { + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NOT_FOUND), UserNicName); + } + +Error: + ShellCommandLineFreeVarList (CheckPackage); + SHELL_FREE_NON_NULL (Handles); + SHELL_FREE_NON_NULL (Context.ServerAddrAndProto); + SHELL_FREE_NON_NULL (Context.Uri); + + return Status & ~MAX_BIT; +} + +/** + Check and convert the UINT16 option values of the 'http' command + + @param[in] ValueStr Value as an Unicode encoded string + @param[out] Value UINT16 value + + @retval TRUE The value was returned. + @retval FALSE A parsing error occured. +**/ +STATIC +BOOLEAN +StringToUint16 ( + IN CONST CHAR16 *ValueStr, + OUT UINT16 *Value + ) +{ + UINTN Val; + + Val = ShellStrToUintn (ValueStr); + if (Val > MAX_UINT16) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr); + return FALSE; + } + + *Value = (UINT16)Val; + return TRUE; +} + +/** + Get the name of the NIC. + + @param[in] ControllerHandle The network physical device handle. + @param[in] NicNumber The network physical device number. + @param[out] NicName Address where to store the NIC name. + The memory area has to be at least + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH + double byte wide. + + @retval EFI_SUCCESS The name of the NIC was returned. + @retval Others The creation of the child for the Managed + Network Service failed or the opening of + the Managed Network Protocol failed or + the operational parameters for the + Managed Network Protocol could not be + read. +**/ +STATIC +EFI_STATUS +GetNicName ( + IN EFI_HANDLE ControllerHandle, + IN UINTN NicNumber, + OUT CHAR16 *NicName + ) +{ + EFI_STATUS Status; + EFI_HANDLE MnpHandle; + EFI_MANAGED_NETWORK_PROTOCOL *Mnp; + EFI_SIMPLE_NETWORK_MODE SnpMode; + + Status = CreateServiceChildAndOpenProtocol ( + ControllerHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid, + &gEfiManagedNetworkProtocolGuid, + &MnpHandle, + (VOID **)&Mnp + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = Mnp->GetModeData (Mnp, NULL, &SnpMode); + if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) { + goto Error; + } + + UnicodeSPrint ( + NicName, + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH, + SnpMode.IfType == NET_IFTYPE_ETHERNET ? L"eth%d" : L"unk%d", + NicNumber + ); + + Status = EFI_SUCCESS; + +Error: + + if (MnpHandle != NULL) { + CloseProtocolAndDestroyServiceChild ( + ControllerHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid, + &gEfiManagedNetworkProtocolGuid, + MnpHandle + ); + } + + return Status; +} + +/** + Create a child for the service identified by its service binding protocol GUID + and get from the child the interface of the protocol identified by its GUID. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be created. + @param[in] ProtocolGuid GUID of the protocol to be open. + @param[out] ChildHandle Address where the handler of the + created child is returned. NULL is + returned in case of error. + @param[out] Interface Address where a pointer to the + protocol interface is returned in + case of success. + + @retval EFI_SUCCESS The child was created and the protocol opened. + @retval Others Either the creation of the child or the opening + of the protocol failed. +**/ +STATIC +EFI_STATUS +CreateServiceChildAndOpenProtocol ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + OUT EFI_HANDLE *ChildHandle, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + *ChildHandle = NULL; + Status = NetLibCreateServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + ChildHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + *ChildHandle, + ProtocolGuid, + Interface, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + NetLibDestroyServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + *ChildHandle + ); + *ChildHandle = NULL; + } + } + + return Status; +} + +/** + Close the protocol identified by its GUID on the child handle of the service + identified by its service binding protocol GUID, then destroy the child + handle. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be destroyed. + @param[in] ProtocolGuid GUID of the protocol to be closed. + @param[in] ChildHandle Handle of the child to be destroyed. +**/ +STATIC +VOID +CloseProtocolAndDestroyServiceChild ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + IN EFI_HANDLE ChildHandle + ) +{ + gBS->CloseProtocol ( + ChildHandle, + ProtocolGuid, + gImageHandle, + ControllerHandle + ); + + NetLibDestroyServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + ChildHandle + ); +} + +/** + Wait until operation completes. Completion is indicated by + setting of an appropriate variable. + + @param[in] Context A pointer to the HTTP download context. + @param[in, out] CallBackComplete A pointer to the callback completion + variable set by the callback. + + @retval EFI_SUCCESS Callback signalled completion. + @retval EFI_TIMEOUT Timed out waiting for completion. + @retval Others Error waiting for completion. +**/ +STATIC +EFI_STATUS +WaitForCompletion ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN OUT BOOLEAN *CallBackComplete + ) +{ + EFI_STATUS Status; + EFI_EVENT WaitEvt; + + Status = EFI_SUCCESS; + + // + // Use a timer to measure timeout. Cannot use Stall here! + // + Status = gBS->CreateEvent ( + EVT_TIMER, + TPL_CALLBACK, + NULL, + NULL, + &WaitEvt + ); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR (Status)) { + Status = gBS->SetTimer ( + WaitEvt, + TimerRelative, + EFI_TIMER_PERIOD_SECONDS (TIMER_MAX_TIMEOUT_S) + ); + + ASSERT_EFI_ERROR (Status); + } + + while ( !*CallBackComplete + && (!EFI_ERROR (Status)) + && EFI_ERROR (gBS->CheckEvent (WaitEvt))) + { + Status = Context->Http->Poll (Context->Http); + if ( !Context->ContentDownloaded + && (CallBackComplete == &gResponseCallbackComplete)) + { + // + // An HTTP server may just send a response redirection header. + // In this case, don't wait for the event as + // it might never happen and we waste 10s waiting. + // Note that at this point Response may not has been populated, + // so it needs to be checked first. + // + if ( Context->ResponseToken.Message + && Context->ResponseToken.Message->Data.Response + && (NEED_REDIRECTION ( + Context->ResponseToken.Message->Data.Response->StatusCode + ) + )) + { + break; + } + } + } + + gBS->SetTimer (WaitEvt, TimerCancel, 0); + gBS->CloseEvent (WaitEvt); + + if (*CallBackComplete) { + return EFI_SUCCESS; + } + + if (!EFI_ERROR (Status)) { + Status = EFI_TIMEOUT; + } + + return Status; +} + +/** + Generate and send a request to the http server. + + @param[in] Context HTTP download context. + @param[in] DownloadUrl Fully qualified URL to be downloaded. + + @retval EFI_SUCCESS Request has been sent successfully. + @retval EFI_INVALID_PARAMETER Invalid URL. + @retval EFI_OUT_OF_RESOURCES Out of memory. + @retval EFI_DEVICE_ERROR If HTTPS is used, this probably + means that TLS support either was not + installed or not configured. + @retval Others Error sending the request. +**/ +STATIC +EFI_STATUS +SendRequest ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN CHAR16 *DownloadUrl + ) +{ + EFI_HTTP_REQUEST_DATA RequestData; + EFI_HTTP_HEADER RequestHeader[HdrMax]; + EFI_HTTP_MESSAGE RequestMessage; + EFI_STATUS Status; + CHAR16 *Host; + UINTN StringSize; + + ZeroMem (&RequestData, sizeof (RequestData)); + ZeroMem (&RequestHeader, sizeof (RequestHeader)); + ZeroMem (&RequestMessage, sizeof (RequestMessage)); + ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken)); + + RequestHeader[HdrHost].FieldName = "Host"; + RequestHeader[HdrConn].FieldName = "Connection"; + RequestHeader[HdrAgent].FieldName = "User-Agent"; + + Host = (CHAR16 *)Context->ServerAddrAndProto; + while (*Host != CHAR_NULL && *Host != L'/') { + Host++; + } + + if (*Host == CHAR_NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Get the next slash. + // + Host++; + // + // And now the host name. + // + Host++; + + StringSize = StrLen (Host) + 1; + RequestHeader[HdrHost].FieldValue = AllocatePool (StringSize); + if (!RequestHeader[HdrHost].FieldValue) { + return EFI_OUT_OF_RESOURCES; + } + + UnicodeStrToAsciiStrS ( + Host, + RequestHeader[HdrHost].FieldValue, + StringSize + ); + + RequestHeader[HdrConn].FieldValue = "close"; + RequestHeader[HdrAgent].FieldValue = USER_AGENT_HDR; + RequestMessage.HeaderCount = HdrMax; + + RequestData.Method = HttpMethodGet; + RequestData.Url = DownloadUrl; + + RequestMessage.Data.Request = &RequestData; + RequestMessage.Headers = RequestHeader; + RequestMessage.BodyLength = 0; + RequestMessage.Body = NULL; + Context->RequestToken.Event = NULL; + + // + // Completion callback event to be set when Request completes. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RequestCallback, + Context, + &Context->RequestToken.Event + ); + ASSERT_EFI_ERROR (Status); + + Context->RequestToken.Status = EFI_SUCCESS; + Context->RequestToken.Message = &RequestMessage; + gRequestCallbackComplete = FALSE; + Status = Context->Http->Request (Context->Http, &Context->RequestToken); + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = WaitForCompletion (Context, &gRequestCallbackComplete); + if (EFI_ERROR (Status)) { + Context->Http->Cancel (Context->Http, &Context->RequestToken); + } + +Error: + SHELL_FREE_NON_NULL (RequestHeader[HdrHost].FieldValue); + if (Context->RequestToken.Event) { + gBS->CloseEvent (Context->RequestToken.Event); + ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken)); + } + + return Status; +} + +/** + Update the progress of a file download + This procedure is called each time a new HTTP body portion is received. + + @param[in] Context HTTP download context. + @param[in] DownloadLen Portion size, in bytes. + @param[in] Buffer The pointer to the parsed buffer. + + @retval EFI_SUCCESS Portion saved. + @retval Other Error saving the portion. +**/ +STATIC +EFI_STATUS +EFIAPI +SavePortion ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN UINTN DownloadLen, + IN CHAR8 *Buffer + ) +{ + CHAR16 Progress[HTTP_PROGRESS_MESSAGE_SIZE]; + UINTN NbOfKb; + UINTN Index; + UINTN LastStep; + UINTN Step; + EFI_STATUS Status; + + LastStep = 0; + Step = 0; + + ShellSetFilePosition (mFileHandle, Context->LastReportedNbOfBytes); + Status = ShellWriteFile (mFileHandle, &DownloadLen, Buffer); + if (EFI_ERROR (Status)) { + if (Context->ContentDownloaded > 0) { + PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL); + } + + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_WRITE), mLocalFilePath, Status); + return Status; + } + + if (Context->ContentDownloaded == 0) { + ShellPrintEx (-1, -1, L"%s 0 Kb", HTTP_PROGR_FRAME); + } + + Context->ContentDownloaded += DownloadLen; + NbOfKb = Context->ContentDownloaded >> 10; + + Progress[0] = L'\0'; + if (Context->ContentLength) { + LastStep = (Context->LastReportedNbOfBytes * HTTP_PROGRESS_SLIDER_STEPS) / + Context->ContentLength; + Step = (Context->ContentDownloaded * HTTP_PROGRESS_SLIDER_STEPS) / + Context->ContentLength; + } + + Context->LastReportedNbOfBytes = Context->ContentDownloaded; + + if (Step <= LastStep) { + if (!Context->ContentLength) { + // + // Update downloaded size, there is no length info available. + // + ShellPrintEx (-1, -1, L"%s", HTTP_KB); + ShellPrintEx (-1, -1, L"%7d Kb", NbOfKb); + } + + return EFI_SUCCESS; + } + + ShellPrintEx (-1, -1, L"%s", HTTP_PROGRESS_DEL); + + Status = StrCpyS (Progress, HTTP_PROGRESS_MESSAGE_SIZE, HTTP_PROGR_FRAME); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 1; Index < Step; Index++) { + Progress[Index] = L'='; + } + + if (Step) { + Progress[Step] = L'>'; + } + + UnicodeSPrint ( + Progress + (sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 1, + sizeof (Progress) - sizeof (HTTP_PROGR_FRAME), + L" %7d Kb", + NbOfKb + ); + + ShellPrintEx (-1, -1, L"%s", Progress); + + return EFI_SUCCESS; +} + +/** + Replace the original Host and Uri with Host and Uri returned by the + HTTP server in 'Location' header (redirection). + + @param[in] Location A pointer to the 'Location' string + provided by HTTP server. + @param[in] Context A pointer to HTTP download context. + @param[in] DownloadUrl Fully qualified HTTP URL. + + @retval EFI_SUCCESS Host and Uri were successfully set. + @retval EFI_OUT_OF_RESOURCES Error setting Host or Uri. +**/ +STATIC +EFI_STATUS +SetHostURI ( + IN CHAR8 *Location, + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN CHAR16 *DownloadUrl + ) +{ + EFI_STATUS Status; + UINTN StringSize; + UINTN FirstStep; + UINTN Idx; + UINTN Step; + CHAR8 *Walker; + CHAR16 *Temp; + CHAR8 *Tmp; + CHAR16 *Url; + BOOLEAN IsAbEmptyUrl; + + Tmp = NULL; + Url = NULL; + IsAbEmptyUrl = FALSE; + FirstStep = 0; + + StringSize = (AsciiStrSize (Location) * sizeof (CHAR16)); + Url = AllocateZeroPool (StringSize); + if (!Url) { + return EFI_OUT_OF_RESOURCES; + } + + Status = AsciiStrToUnicodeStrS ( + (CONST CHAR8 *)Location, + Url, + StringSize + ); + + if (EFI_ERROR (Status)) { + goto Error; + } + + // + // If an HTTP server redirects to the same location more than once, + // then stop attempts and tell it is not reachable. + // + if (!StrCmp (Url, DownloadUrl)) { + Status = EFI_NO_MAPPING; + goto Error; + } + + if (AsciiStrLen (Location) > 2) { + // + // Some servers return 'Location: //server/resource' + // + IsAbEmptyUrl = (Location[0] == '/') && (Location[1] == '/'); + if (IsAbEmptyUrl) { + // + // Skip first "//" + // + Location += 2; + FirstStep = 1; + } + } + + if (AsciiStrStr (Location, "://") || IsAbEmptyUrl) { + Idx = 0; + Walker = Location; + + for (Step = FirstStep; Step < 2; Step++) { + for ( ; *Walker != '/' && *Walker != '\0'; Walker++) { + Idx++; + } + + if (!Step) { + // + // Skip "//" + // + Idx += 2; + Walker += 2; + } + } + + Tmp = AllocateZeroPool (Idx + 1); + if (!Tmp) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + CopyMem (Tmp, Location, Idx); + + // + // Location now points to Uri + // + Location += Idx; + StringSize = (Idx + 1) * sizeof (CHAR16); + + SHELL_FREE_NON_NULL (Context->ServerAddrAndProto); + + Temp = AllocateZeroPool (StringSize); + if (!Temp) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + Status = AsciiStrToUnicodeStrS ( + (CONST CHAR8 *)Tmp, + Temp, + StringSize + ); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (Temp); + goto Error; + } + + Idx = 0; + if (IsAbEmptyUrl) { + Context->ServerAddrAndProto = StrnCatGrow ( + &Context->ServerAddrAndProto, + &Idx, + L"http://", + StrLen (L"http://") + ); + } + + Context->ServerAddrAndProto = StrnCatGrow ( + &Context->ServerAddrAndProto, + &Idx, + Temp, + StrLen (Temp) + ); + SHELL_FREE_NON_NULL (Temp); + if (!Context->ServerAddrAndProto) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + } + + SHELL_FREE_NON_NULL (Context->Uri); + + StringSize = AsciiStrSize (Location) * sizeof (CHAR16); + Context->Uri = AllocateZeroPool (StringSize); + if (!Context->Uri) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Now make changes to the Uri part. + // + Status = AsciiStrToUnicodeStrS ( + (CONST CHAR8 *)Location, + Context->Uri, + StringSize + ); +Error: + SHELL_FREE_NON_NULL (Tmp); + SHELL_FREE_NON_NULL (Url); + + return Status; +} + +/** + Message parser callback. + Save a portion of HTTP body. + + @param[in] EventType Type of event. Can be either + OnComplete or OnData. + @param[in] Data A pointer to the buffer with data. + @param[in] Length Data length of this portion. + @param[in] Context A pointer to the HTTP download context. + + @retval EFI_SUCCESS The portion was processed successfully. + @retval Other Error returned by SavePortion. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMsg ( + IN HTTP_BODY_PARSE_EVENT EventType, + IN CHAR8 *Data, + IN UINTN Length, + IN VOID *Context + ) +{ + if ( (Data == NULL) + || (EventType == BodyParseEventOnComplete) + || (Context == NULL)) + { + return EFI_SUCCESS; + } + + return SavePortion (Context, Length, Data); +} + +/** + Get HTTP server response and collect the whole body as a file. + Set appropriate status in Context (REQ_OK, REQ_REPEAT, REQ_ERROR). + Note that even if HTTP server returns an error code, it might send + the body as well. This body will be collected in the resultant file. + + @param[in] Context A pointer to the HTTP download context. + @param[in] DownloadUrl A pointer to the fully qualified URL to download. + + @retval EFI_SUCCESS Valid file. Body successfully collected. + @retval EFI_HTTP_ERROR Response is a valid HTTP response, but the + HTTP server + indicated an error (HTTP code >= 400). + Response body MAY contain full + HTTP server response. + @retval Others Error getting the reponse from the HTTP server. + Response body is not collected. +**/ +STATIC +EFI_STATUS +GetResponse ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN CHAR16 *DownloadUrl + ) +{ + EFI_HTTP_RESPONSE_DATA ResponseData; + EFI_HTTP_MESSAGE ResponseMessage; + EFI_HTTP_HEADER *Header; + EFI_STATUS Status; + VOID *MsgParser; + EFI_TIME StartTime; + EFI_TIME EndTime; + CONST CHAR16 *Desc; + UINTN ElapsedSeconds; + BOOLEAN IsTrunked; + BOOLEAN CanMeasureTime; + + ZeroMem (&ResponseData, sizeof (ResponseData)); + ZeroMem (&ResponseMessage, sizeof (ResponseMessage)); + ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken)); + IsTrunked = FALSE; + + ResponseMessage.Body = Context->Buffer; + Context->ResponseToken.Status = EFI_SUCCESS; + Context->ResponseToken.Message = &ResponseMessage; + Context->ContentLength = 0; + Context->Status = REQ_OK; + Status = EFI_SUCCESS; + MsgParser = NULL; + ResponseData.StatusCode = HTTP_STATUS_UNSUPPORTED_STATUS; + ResponseMessage.Data.Response = &ResponseData; + Context->ResponseToken.Event = NULL; + CanMeasureTime = FALSE; + if (Context->Flags & DL_FLAG_TIME) { + ZeroMem (&StartTime, sizeof (StartTime)); + CanMeasureTime = !EFI_ERROR (gRT->GetTime (&StartTime, NULL)); + } + + do { + SHELL_FREE_NON_NULL (ResponseMessage.Headers); + ResponseMessage.HeaderCount = 0; + gResponseCallbackComplete = FALSE; + ResponseMessage.BodyLength = Context->BufferSize; + + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + + if (!Context->ContentDownloaded && !Context->ResponseToken.Event) { + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + ResponseCallback, + Context, + &Context->ResponseToken.Event + ); + ASSERT_EFI_ERROR (Status); + } else { + ResponseMessage.Data.Response = NULL; + } + + if (EFI_ERROR (Status)) { + break; + } + + Status = Context->Http->Response (Context->Http, &Context->ResponseToken); + if (EFI_ERROR (Status)) { + break; + } + + Status = WaitForCompletion (Context, &gResponseCallbackComplete); + if (EFI_ERROR (Status) && ResponseMessage.HeaderCount) { + Status = EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + Context->Http->Cancel (Context->Http, &Context->ResponseToken); + break; + } + + if (!Context->ContentDownloaded) { + if (NEED_REDIRECTION (ResponseData.StatusCode)) { + // + // Need to repeat the request with new Location (server redirected). + // + Context->Status = REQ_NEED_REPEAT; + + Header = HttpFindHeader ( + ResponseMessage.HeaderCount, + ResponseMessage.Headers, + "Location" + ); + if (Header) { + Status = SetHostURI (Header->FieldValue, Context, DownloadUrl); + if (Status == EFI_NO_MAPPING) { + PRINT_HII ( + STRING_TOKEN (STR_HTTP_ERR_STATUSCODE), + Context->ServerAddrAndProto, + L"Recursive HTTP server relocation", + Context->Uri + ); + } + } else { + // + // Bad reply from the server. Server must specify the location. + // Indicate that resource was not found, and no body collected. + // + Status = EFI_NOT_FOUND; + } + + Context->Http->Cancel (Context->Http, &Context->ResponseToken); + break; + } + + // + // Init message-body parser by header information. + // + if (!MsgParser) { + Status = HttpInitMsgParser ( + ResponseMessage.Data.Request->Method, + ResponseData.StatusCode, + ResponseMessage.HeaderCount, + ResponseMessage.Headers, + ParseMsg, + Context, + &MsgParser + ); + if (EFI_ERROR (Status)) { + break; + } + } + + // + // If it is a trunked message, rely on the parser. + // + Header = HttpFindHeader ( + ResponseMessage.HeaderCount, + ResponseMessage.Headers, + "Transfer-Encoding" + ); + IsTrunked = (Header && !AsciiStrCmp (Header->FieldValue, "chunked")); + + HttpGetEntityLength (MsgParser, &Context->ContentLength); + + if ( (ResponseData.StatusCode >= HTTP_STATUS_400_BAD_REQUEST) + && (ResponseData.StatusCode != HTTP_STATUS_308_PERMANENT_REDIRECT)) + { + // + // Server reported an error via Response code. + // Collect the body if any. + // + if (!gHttpError) { + gHttpError = TRUE; + + Desc = ErrStatusDesc[ResponseData.StatusCode - + HTTP_STATUS_400_BAD_REQUEST]; + PRINT_HII ( + STRING_TOKEN (STR_HTTP_ERR_STATUSCODE), + Context->ServerAddrAndProto, + Desc, + Context->Uri + ); + + // + // This gives an RFC HTTP error. + // + Context->Status = ShellStrToUintn (Desc); + Status = ENCODE_ERROR (Context->Status); + } + } + } + + // + // Do NOT try to parse an empty body. + // + if (ResponseMessage.BodyLength || IsTrunked) { + Status = HttpParseMessageBody ( + MsgParser, + ResponseMessage.BodyLength, + ResponseMessage.Body + ); + } + } while ( !HttpIsMessageComplete (MsgParser) + && !EFI_ERROR (Status) + && ResponseMessage.BodyLength); + + if ( (Context->Status != REQ_NEED_REPEAT) + && (Status == EFI_SUCCESS) + && CanMeasureTime) + { + if (!EFI_ERROR (gRT->GetTime (&EndTime, NULL))) { + ElapsedSeconds = EfiTimeToEpoch (&EndTime) - EfiTimeToEpoch (&StartTime); + Print ( + L",%a%Lus\n", + ElapsedSeconds ? " " : " < ", + ElapsedSeconds > 1 ? (UINT64)ElapsedSeconds : 1 + ); + } + } + + SHELL_FREE_NON_NULL (MsgParser); + if (Context->ResponseToken.Event) { + gBS->CloseEvent (Context->ResponseToken.Event); + ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken)); + } + + return Status; +} + +/** + Worker function that downloads the data of a file from an HTTP server given + the path of the file and its size. + + @param[in] Context A pointer to the HTTP download context. + @param[in] ControllerHandle The handle of the network interface controller + @param[in] NicName NIC name + + @retval EFI_SUCCESS The file was downloaded. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + #return EFI_HTTP_ERROR The server returned a valid HTTP error. + Examine the mLocalFilePath file + to get error body. + @retval Others The downloading of the file from the server + failed. +**/ +STATIC +EFI_STATUS +DownloadFile ( + IN HTTP_DOWNLOAD_CONTEXT *Context, + IN EFI_HANDLE ControllerHandle, + IN CHAR16 *NicName + ) +{ + EFI_STATUS Status; + CHAR16 *DownloadUrl; + UINTN UrlSize; + EFI_HANDLE HttpChildHandle; + + ASSERT (Context); + if (Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + DownloadUrl = NULL; + HttpChildHandle = NULL; + + Context->Buffer = AllocatePool (Context->BufferSize); + if (Context->Buffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Open the file. + // + if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) { + ShellDeleteFileByName (mLocalFilePath); + } + + Status = ShellOpenFileByName ( + mLocalFilePath, + &mFileHandle, + EFI_FILE_MODE_CREATE | + EFI_FILE_MODE_WRITE | + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + PRINT_HII_APP (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), mLocalFilePath); + goto ON_EXIT; + } + + do { + SHELL_FREE_NON_NULL (DownloadUrl); + + CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle); + + Status = CreateServiceChildAndOpenProtocol ( + ControllerHandle, + &gEfiHttpServiceBindingProtocolGuid, + &gEfiHttpProtocolGuid, + &HttpChildHandle, + (VOID **)&Context->Http + ); + + if (EFI_ERROR (Status)) { + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_OPEN_PROTOCOL), NicName, Status); + goto ON_EXIT; + } + + Status = Context->Http->Configure (Context->Http, &Context->HttpConfigData); + if (EFI_ERROR (Status)) { + PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_CONFIGURE), NicName, Status); + goto ON_EXIT; + } + + UrlSize = 0; + DownloadUrl = StrnCatGrow ( + &DownloadUrl, + &UrlSize, + Context->ServerAddrAndProto, + StrLen (Context->ServerAddrAndProto) + ); + if (Context->Uri[0] != L'/') { + DownloadUrl = StrnCatGrow ( + &DownloadUrl, + &UrlSize, + L"/", + StrLen (Context->ServerAddrAndProto) + ); + } + + DownloadUrl = StrnCatGrow ( + &DownloadUrl, + &UrlSize, + Context->Uri, + StrLen (Context->Uri) + ); + + PRINT_HII (STRING_TOKEN (STR_HTTP_DOWNLOADING), DownloadUrl); + + Status = SendRequest (Context, DownloadUrl); + if (Status) { + goto ON_EXIT; + } + + Status = GetResponse (Context, DownloadUrl); + + if (Status) { + goto ON_EXIT; + } + } while (Context->Status == REQ_NEED_REPEAT); + + if (Context->Status) { + Status = ENCODE_ERROR (Context->Status); + } + +ON_EXIT: + // + // Close the file. + // + if (mFileHandle != NULL) { + if (EFI_ERROR (Status) && !(Context->Flags & DL_FLAG_KEEP_BAD)) { + ShellDeleteFile (&mFileHandle); + } else { + ShellCloseFile (&mFileHandle); + } + } + + SHELL_FREE_NON_NULL (DownloadUrl); + SHELL_FREE_NON_NULL (Context->Buffer); + + CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle); + + return Status; +} + +/** + Retrive HII package list from ImageHandle and publish to HII database. + + @param[in] ImageHandle The image handle of the process. + + @retval HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + EFI_HII_HANDLE HiiHandle; + + // + // Retrieve HII package list from ImageHandle. + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **)&PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + // + // Publish HII package list to HII Database. + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &HiiHandle + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + return HiiHandle; +} diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h index f6c4b2c537..a5bd6273e0 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h @@ -1,93 +1,93 @@ -/** @file
- Header file for 'http' command functions.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _HTTP_H_
-#define _HTTP_H_
-
-#include <Uefi.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/HiiLib.h>
-#include <Library/HttpLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/NetLib.h>
-#include <Library/PrintLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiHiiServicesLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-
-#include <Protocol/HiiPackageList.h>
-#include <Protocol/HttpUtilities.h>
-#include <Protocol/ServiceBinding.h>
-
-#define HTTP_APP_NAME L"http"
-
-#define REQ_OK 0
-#define REQ_NEED_REPEAT 1
-
-//
-// Download Flags.
-//
-#define DL_FLAG_TIME BIT0 // Show elapsed time.
-#define DL_FLAG_KEEP_BAD BIT1 // Keep files even if download failed.
-
-extern EFI_HII_HANDLE mHttpHiiHandle;
-
-typedef struct {
- UINTN ContentDownloaded;
- UINTN ContentLength;
- UINTN LastReportedNbOfBytes;
- UINTN BufferSize;
- UINTN Status;
- UINTN Flags;
- UINT8 *Buffer;
- CHAR16 *ServerAddrAndProto;
- CHAR16 *Uri;
- EFI_HTTP_TOKEN ResponseToken;
- EFI_HTTP_TOKEN RequestToken;
- EFI_HTTP_PROTOCOL *Http;
- EFI_HTTP_CONFIG_DATA HttpConfigData;
-} HTTP_DOWNLOAD_CONTEXT;
-
-/**
- Function for 'http' command.
-
- @param[in] ImageHandle The image handle.
- @param[in] SystemTable The system table.
-
- @retval SHELL_SUCCESS Command completed successfully.
- @retval SHELL_INVALID_PARAMETER Command usage error.
- @retval SHELL_ABORTED The user aborts the operation.
- @retval value Unknown error.
-**/
-SHELL_STATUS
-RunHttp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param[in] ImageHandle The image handle of the process.
-
- @retval HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- IN EFI_HANDLE ImageHandle
- );
-
-#endif // _HTTP_H_
+/** @file + Header file for 'http' command functions. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2020, Broadcom. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _HTTP_H_ +#define _HTTP_H_ + +#include <Uefi.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/HiiLib.h> +#include <Library/HttpLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/NetLib.h> +#include <Library/PrintLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiHiiServicesLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> + +#include <Protocol/HiiPackageList.h> +#include <Protocol/HttpUtilities.h> +#include <Protocol/ServiceBinding.h> + +#define HTTP_APP_NAME L"http" + +#define REQ_OK 0 +#define REQ_NEED_REPEAT 1 + +// +// Download Flags. +// +#define DL_FLAG_TIME BIT0 // Show elapsed time. +#define DL_FLAG_KEEP_BAD BIT1 // Keep files even if download failed. + +extern EFI_HII_HANDLE mHttpHiiHandle; + +typedef struct { + UINTN ContentDownloaded; + UINTN ContentLength; + UINTN LastReportedNbOfBytes; + UINTN BufferSize; + UINTN Status; + UINTN Flags; + UINT8 *Buffer; + CHAR16 *ServerAddrAndProto; + CHAR16 *Uri; + EFI_HTTP_TOKEN ResponseToken; + EFI_HTTP_TOKEN RequestToken; + EFI_HTTP_PROTOCOL *Http; + EFI_HTTP_CONFIG_DATA HttpConfigData; +} HTTP_DOWNLOAD_CONTEXT; + +/** + Function for 'http' command. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval SHELL_SUCCESS Command completed successfully. + @retval SHELL_INVALID_PARAMETER Command usage error. + @retval SHELL_ABORTED The user aborts the operation. + @retval value Unknown error. +**/ +SHELL_STATUS +RunHttp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param[in] ImageHandle The image handle of the process. + + @retval HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + IN EFI_HANDLE ImageHandle + ); + +#endif // _HTTP_H_ diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni index 00cf05deeb..170b29cd24 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni @@ -1,117 +1,117 @@ -// /**
-//
-// (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
-// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
-// Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Module Name:
-//
-// Http.uni
-//
-// Abstract:
-//
-// String definitions for UEFI Shell HTTP command
-//
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments. Try help http.\r\n"
-#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments. Try help http.\r\n"
-#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'. Try help http.\r\n"
-#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'. Try help http.\r\n"
-#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
-#string STR_GEN_CRLF #language en-US "\r\n"
-
-#string STR_HTTP_ERR_NO_NIC #language en-US "No network interface card found.\r\n"
-#string STR_HTTP_ERR_NIC_NAME #language en-US "Failed to get the name of the network interface card number %d - %r\r\n"
-#string STR_HTTP_ERR_OPEN_PROTOCOL #language en-US "Unable to open HTTP protocol on '%H%s%N' - %r\r\n"
-#string STR_HTTP_ERR_CONFIGURE #language en-US "Unable to configure HTTP protocol on '%H%s%N' - %r\r\n"
-#string STR_HTTP_ERR_DOWNLOAD #language en-US "Unable to download the file '%H%s%N' on '%H%s%N' - %r\r\n"
-#string STR_HTTP_ERR_WRITE #language en-US "Unable to write into file '%H%s%N' - %r\r\n"
-#string STR_HTTP_ERR_NIC_NOT_FOUND #language en-US "Network Interface Card '%H%s%N' not found.\r\n"
-#string STR_HTTP_ERR_STATUSCODE #language en-US "\r'%H%s%N' reports '%s' for '%H%s%N' \r\n"
-#string STR_HTTP_DOWNLOADING #language en-US "Downloading '%H%s%N'\r\n"
-
-#string STR_GET_HELP_HTTP #language en-US ""
-".TH http 0 "Download a file from HTTP server."\r\n"
-".SH NAME\r\n"
-"Download a file from HTTP server.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"HTTP [-i interface] [-l port] [-t timeout] [-s size] [-m] [-k]\r\n"
-" <URL> [localfilepath]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -i interface - Specifies an adapter name, i.e., eth0.\r\n"
-" -k Keep the downloaded file even if there was an error.\r\n"
-" If this parameter is not used, the file will be deleted.\r\n"
-" -l port - Specifies the local port number. Default value is 0\r\n"
-" and the port number is automatically assigned.\r\n"
-" -m Measure and report download time (in seconds). \r\n"
-" -s size The size of the download buffer for a chunk, in bytes.\r\n"
-" Default is 32K. Note that larger buffer does not imply\r\n"
-" better speed.\r\n"
-" -t timeout - The number of seconds to wait for completion of\r\n"
-" requests and responses. Default is 0 which is 'automatic'.\r\n"
-" %HURL%N\r\n"
-" Two types of providing of URLs are supported:\r\n"
-" 1. tftp-like, where host and http_uri are separate parameters\r\n"
-" (example: host /host_uri), and\r\n\"
-" 2. wget-like, where host and host_uri is one parameter.\r\n"
-" (example: host/host_uri)\r\n"
-"\r\n"
-" host - Specifies HTTP Server address.\r\n
- Can be either IPv4 address or 'http (or https)://addr'\r\n
- Can use addresses resolvable by DNS as well. \r\n
- Port can be specified after ':' if needed. \r\n
- By default port 80 is used.\r\n"
-" http_uri - HTTP server URI to download the file.\r\n"
-"\r\n"
-" localfilepath - Local destination file path.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. The HTTP command allows geting of the file specified by its 'http_uri'\r\n"
-" path from the HTTP server specified by its 'host' IPv4 address. If the\r\n"
-" optional 'localfilepath' parameter is provided, the downloaded file is\r\n"
-" stored locally using the provided file path. If the local file path is\r\n"
-" not specified, the file is stored in the current directory using the file\r\n"
-" server's name.\r\n"
-" 2. Before using the HTTP command, the network interface intended to be\r\n"
-" used to retrieve the file must be configured. This configuration may be\r\n"
-" done by means of the 'ifconfig' command.\r\n"
-" 3. If a network interface is defined with the '-i' option then only this\r\n"
-" interface will be used to retrieve the remote file. Otherwise, all network\r\n"
-" interfaces are tried in the order they have been discovered during the\r\n"
-" DXE phase.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To get the file "dir1/file1.dat" from the HTTP server 192.168.1.1, port 8080, and\r\n"
-" store it as file2.dat in the current directory (use tftp-like URL format) :\r\n"
-" fs0:\> http 192.168.1.1:8080 dir1/file1.dat file2.dat\r\n"
-" * To get the file /image.bin via HTTPS from server 192.168.1.1 at port 443 \r\n"
-" (default HTTPS port), and store it in the current directory: \r\n"
-" fs0:\> http https://192.168.1.1 image.bin\r\n"
-" To get an index file from http://google.com and place it into the \r\n"
-" current directory:\r\n"
-" fs0:\> http google.com index.html\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" HTTP_ERROR No EFI errors, but the server reported a status code\r\n"
-" which should be treated as an error. If an error body sent\r\n"
-" by the server, and -k parameter is on command line,
-" the file wil be saved either as localfilepath filename,\r\n"
-" or as an URI name in the current directory.\r\n"
-" If '/' is at the end of the URL, and no locafilepath filename\r\n"
-" is given on the command line, the file will be retrieved as\r\n"
-" index.html.\r\n"
+// /** +// +// (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR> +// Copyright (c) 2020, Broadcom. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// Http.uni +// +// Abstract: +// +// String definitions for UEFI Shell HTTP command +// +// +// **/ + +/=# + +#langdef en-US "english" + +#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments. Try help http.\r\n" +#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments. Try help http.\r\n" +#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'. Try help http.\r\n" +#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'. Try help http.\r\n" +#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n" +#string STR_GEN_CRLF #language en-US "\r\n" + +#string STR_HTTP_ERR_NO_NIC #language en-US "No network interface card found.\r\n" +#string STR_HTTP_ERR_NIC_NAME #language en-US "Failed to get the name of the network interface card number %d - %r\r\n" +#string STR_HTTP_ERR_OPEN_PROTOCOL #language en-US "Unable to open HTTP protocol on '%H%s%N' - %r\r\n" +#string STR_HTTP_ERR_CONFIGURE #language en-US "Unable to configure HTTP protocol on '%H%s%N' - %r\r\n" +#string STR_HTTP_ERR_DOWNLOAD #language en-US "Unable to download the file '%H%s%N' on '%H%s%N' - %r\r\n" +#string STR_HTTP_ERR_WRITE #language en-US "Unable to write into file '%H%s%N' - %r\r\n" +#string STR_HTTP_ERR_NIC_NOT_FOUND #language en-US "Network Interface Card '%H%s%N' not found.\r\n" +#string STR_HTTP_ERR_STATUSCODE #language en-US "\r'%H%s%N' reports '%s' for '%H%s%N' \r\n" +#string STR_HTTP_DOWNLOADING #language en-US "Downloading '%H%s%N'\r\n" + +#string STR_GET_HELP_HTTP #language en-US "" +".TH http 0 "Download a file from HTTP server."\r\n" +".SH NAME\r\n" +"Download a file from HTTP server.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"HTTP [-i interface] [-l port] [-t timeout] [-s size] [-m] [-k]\r\n" +" <URL> [localfilepath]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -i interface - Specifies an adapter name, i.e., eth0.\r\n" +" -k Keep the downloaded file even if there was an error.\r\n" +" If this parameter is not used, the file will be deleted.\r\n" +" -l port - Specifies the local port number. Default value is 0\r\n" +" and the port number is automatically assigned.\r\n" +" -m Measure and report download time (in seconds). \r\n" +" -s size The size of the download buffer for a chunk, in bytes.\r\n" +" Default is 32K. Note that larger buffer does not imply\r\n" +" better speed.\r\n" +" -t timeout - The number of seconds to wait for completion of\r\n" +" requests and responses. Default is 0 which is 'automatic'.\r\n" +" %HURL%N\r\n" +" Two types of providing of URLs are supported:\r\n" +" 1. tftp-like, where host and http_uri are separate parameters\r\n" +" (example: host /host_uri), and\r\n\" +" 2. wget-like, where host and host_uri is one parameter.\r\n" +" (example: host/host_uri)\r\n" +"\r\n" +" host - Specifies HTTP Server address.\r\n + Can be either IPv4 address or 'http (or https)://addr'\r\n + Can use addresses resolvable by DNS as well. \r\n + Port can be specified after ':' if needed. \r\n + By default port 80 is used.\r\n" +" http_uri - HTTP server URI to download the file.\r\n" +"\r\n" +" localfilepath - Local destination file path.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. The HTTP command allows geting of the file specified by its 'http_uri'\r\n" +" path from the HTTP server specified by its 'host' IPv4 address. If the\r\n" +" optional 'localfilepath' parameter is provided, the downloaded file is\r\n" +" stored locally using the provided file path. If the local file path is\r\n" +" not specified, the file is stored in the current directory using the file\r\n" +" server's name.\r\n" +" 2. Before using the HTTP command, the network interface intended to be\r\n" +" used to retrieve the file must be configured. This configuration may be\r\n" +" done by means of the 'ifconfig' command.\r\n" +" 3. If a network interface is defined with the '-i' option then only this\r\n" +" interface will be used to retrieve the remote file. Otherwise, all network\r\n" +" interfaces are tried in the order they have been discovered during the\r\n" +" DXE phase.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To get the file "dir1/file1.dat" from the HTTP server 192.168.1.1, port 8080, and\r\n" +" store it as file2.dat in the current directory (use tftp-like URL format) :\r\n" +" fs0:\> http 192.168.1.1:8080 dir1/file1.dat file2.dat\r\n" +" * To get the file /image.bin via HTTPS from server 192.168.1.1 at port 443 \r\n" +" (default HTTPS port), and store it in the current directory: \r\n" +" fs0:\> http https://192.168.1.1 image.bin\r\n" +" To get an index file from http://google.com and place it into the \r\n" +" current directory:\r\n" +" fs0:\> http google.com index.html\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" +" HTTP_ERROR No EFI errors, but the server reported a status code\r\n" +" which should be treated as an error. If an error body sent\r\n" +" by the server, and -k parameter is on command line, +" the file wil be saved either as localfilepath filename,\r\n" +" or as an URI name in the current directory.\r\n" +" If '/' is at the end of the URL, and no locafilepath filename\r\n" +" is given on the command line, the file will be retrieved as\r\n" +" index.html.\r\n" diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c index ea41417fc3..6c74dce5b1 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c @@ -1,61 +1,61 @@ -/** @file
- Entrypoint of "http" shell standalone application.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "Http.h"
-
-/*
- * String token ID of help message text.
- * Shell supports to find help message in the resource section of an
- * application image if * .MAN file is not found.
- * This global variable is added to make build tool recognizes
- * that the help string is consumed by user and then build tool will
- * add the string into the resource section.
- * Thus the application can use '-?' option to show help message in Shell.
- */
-GLOBAL_REMOVE_IF_UNREFERENCED
-EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_HTTP);
-
-/**
- Entry point of Http standalone application.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Http command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing http command.
-**/
-EFI_STATUS
-EFIAPI
-HttpAppInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
-
- mHttpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mHttpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = EFI_SUCCESS;
-
- ShellStatus = RunHttp (ImageHandle, SystemTable);
-
- HiiRemovePackages (mHttpHiiHandle);
-
- if (Status != SHELL_SUCCESS) {
- Status = ENCODE_ERROR (ShellStatus);
- }
-
- return Status;
-}
+/** @file + Entrypoint of "http" shell standalone application. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2020, Broadcom. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "Http.h" + +/* + * String token ID of help message text. + * Shell supports to find help message in the resource section of an + * application image if * .MAN file is not found. + * This global variable is added to make build tool recognizes + * that the help string is consumed by user and then build tool will + * add the string into the resource section. + * Thus the application can use '-?' option to show help message in Shell. + */ +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_HTTP); + +/** + Entry point of Http standalone application. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Http command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing http command. +**/ +EFI_STATUS +EFIAPI +HttpAppInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + + mHttpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mHttpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = EFI_SUCCESS; + + ShellStatus = RunHttp (ImageHandle, SystemTable); + + HiiRemovePackages (mHttpHiiHandle); + + if (Status != SHELL_SUCCESS) { + Status = ENCODE_ERROR (ShellStatus); + } + + return Status; +} diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf index 27b208b254..bdea1fc17e 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf @@ -1,57 +1,57 @@ -## @file
-# Provides Shell 'http' standalone application.
-#
-# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
-# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-# Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = http
- FILE_GUID = 56B00FB7-91D2-869B-CE5C-26CD1A89C73C
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- ENTRY_POINT = HttpAppInitialize
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Http.c
- HttpApp.c
- Http.h
- Http.uni
-
-[Packages]
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
- NetworkPkg/NetworkPkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- FileHandleLib
- HiiLib
- HttpLib
- MemoryAllocationLib
- NetLib
- ShellLib
- UefiApplicationEntryPoint
- UefiBootServicesTableLib
- UefiHiiServicesLib
- UefiLib
- UefiRuntimeServicesTableLib
-
-[Protocols]
- gEfiHiiPackageListProtocolGuid ## CONSUMES
- gEfiHttpProtocolGuid ## CONSUMES
- gEfiHttpServiceBindingProtocolGuid ## CONSUMES
- gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
+## @file +# Provides Shell 'http' standalone application. +# +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR> +# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> +# Copyright (c) 2020, Broadcom. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = http + FILE_GUID = 56B00FB7-91D2-869B-CE5C-26CD1A89C73C + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = HttpAppInitialize +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Http.c + HttpApp.c + Http.h + Http.uni + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + NetworkPkg/NetworkPkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FileHandleLib + HiiLib + HttpLib + MemoryAllocationLib + NetLib + ShellLib + UefiApplicationEntryPoint + UefiBootServicesTableLib + UefiHiiServicesLib + UefiLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiHiiPackageListProtocolGuid ## CONSUMES + gEfiHttpProtocolGuid ## CONSUMES + gEfiHttpServiceBindingProtocolGuid ## CONSUMES + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c index d3c384dc8b..73ed6bb92d 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c @@ -1,137 +1,137 @@ -/** @file
- Produce "http" shell dynamic command.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include <Protocol/ShellDynamicCommand.h>
-#include "Http.h"
-
-/**
- This is the shell command handler function pointer callback type. This
- function handles the command when it is invoked in the shell.
-
- @param[in] This The instance of the
- EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] SystemTable The pointer to the system table.
- @param[in] ShellParameters The parameters associated with the command.
- @param[in] Shell The instance of the shell protocol used in
- the context of processing this command.
-
- @return EFI_SUCCESS the operation was successful
- @return other the operation failed.
-**/
-SHELL_STATUS
-EFIAPI
-HttpCommandHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- )
-{
- gEfiShellParametersProtocol = ShellParameters;
- gEfiShellProtocol = Shell;
-
- return RunHttp (gImageHandle, SystemTable);
-}
-
-/**
- This is the command help handler function pointer callback type. This
- function is responsible for displaying help information for the associated
- command.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] Language The pointer to the language string to use.
-
- @return string Pool allocated help string, must be freed by caller
-**/
-CHAR16 *
-EFIAPI
-HttpCommandGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- )
-{
- return HiiGetString (
- mHttpHiiHandle,
- STRING_TOKEN (STR_GET_HELP_HTTP),
- Language
- );
-}
-
-EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mHttpDynamicCommand = {
- HTTP_APP_NAME,
- HttpCommandHandler,
- HttpCommandGetHelp
-};
-
-/**
- Entry point of Http Dynamic Command.
-
- Produce the DynamicCommand protocol to handle "http" command.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Http command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing http command.
-**/
-EFI_STATUS
-EFIAPI
-HttpCommandInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mHttpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mHttpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mHttpDynamicCommand
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
-/**
- Http driver unload handler.
-
- @param ImageHandle The image handle of the process.
-
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
-**/
-EFI_STATUS
-EFIAPI
-HttpUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- Status = gBS->UninstallProtocolInterface (
- ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- &mHttpDynamicCommand
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HiiRemovePackages (mHttpHiiHandle);
-
- return EFI_SUCCESS;
-}
+/** @file + Produce "http" shell dynamic command. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2020, Broadcom. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include <Protocol/ShellDynamicCommand.h> +#include "Http.h" + +/** + This is the shell command handler function pointer callback type. This + function handles the command when it is invoked in the shell. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] SystemTable The pointer to the system table. + @param[in] ShellParameters The parameters associated with the command. + @param[in] Shell The instance of the shell protocol used in + the context of processing this command. + + @return EFI_SUCCESS the operation was successful + @return other the operation failed. +**/ +SHELL_STATUS +EFIAPI +HttpCommandHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + gEfiShellParametersProtocol = ShellParameters; + gEfiShellProtocol = Shell; + + return RunHttp (gImageHandle, SystemTable); +} + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed by caller +**/ +CHAR16 * +EFIAPI +HttpCommandGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + return HiiGetString ( + mHttpHiiHandle, + STRING_TOKEN (STR_GET_HELP_HTTP), + Language + ); +} + +EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mHttpDynamicCommand = { + HTTP_APP_NAME, + HttpCommandHandler, + HttpCommandGetHelp +}; + +/** + Entry point of Http Dynamic Command. + + Produce the DynamicCommand protocol to handle "http" command. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Http command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing http command. +**/ +EFI_STATUS +EFIAPI +HttpCommandInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mHttpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mHttpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + EFI_NATIVE_INTERFACE, + &mHttpDynamicCommand + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Http driver unload handler. + + @param ImageHandle The image handle of the process. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. +**/ +EFI_STATUS +EFIAPI +HttpUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status = gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mHttpDynamicCommand + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiRemovePackages (mHttpHiiHandle); + + return EFI_SUCCESS; +} diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf index 159cae214c..2621bcb78d 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf @@ -1,62 +1,62 @@ -## @file
-# Provides Shell 'http' dynamic command.
-#
-# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
-# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-# Copyright (c) 2020, Broadcom. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = httpDynamicCommand
- FILE_GUID = 19618BCE-55AE-09C6-37E9-4CE04084C7A1
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = HttpCommandInitialize
- UNLOAD_IMAGE = HttpUnload
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Http.c
- HttpDynamicCommand.c
- Http.h
- Http.uni
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- NetworkPkg/NetworkPkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- FileHandleLib
- HiiLib
- HttpLib
- MemoryAllocationLib
- NetLib
- ShellLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiHiiServicesLib
- UefiLib
- UefiRuntimeServicesTableLib
-
-[Protocols]
- gEfiHiiPackageListProtocolGuid ## CONSUMES
- gEfiHttpProtocolGuid ## CONSUMES
- gEfiHttpServiceBindingProtocolGuid ## CONSUMES
- gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
- gEfiShellDynamicCommandProtocolGuid ## PRODUCES
-
-[DEPEX]
- TRUE
+## @file +# Provides Shell 'http' dynamic command. +# +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR> +# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> +# Copyright (c) 2020, Broadcom. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = httpDynamicCommand + FILE_GUID = 19618BCE-55AE-09C6-37E9-4CE04084C7A1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = HttpCommandInitialize + UNLOAD_IMAGE = HttpUnload +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Http.c + HttpDynamicCommand.c + Http.h + Http.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FileHandleLib + HiiLib + HttpLib + MemoryAllocationLib + NetLib + ShellLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiHiiServicesLib + UefiLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiHiiPackageListProtocolGuid ## CONSUMES + gEfiHttpProtocolGuid ## CONSUMES + gEfiHttpServiceBindingProtocolGuid ## CONSUMES + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES + gEfiShellDynamicCommandProtocolGuid ## PRODUCES + +[DEPEX] + TRUE diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c index 7e5c73b3da..01614a2e66 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c @@ -1,1248 +1,1248 @@ -/** @file
- The implementation for the 'tftp' Shell command.
-
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
- (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include "Tftp.h"
-
-#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
-EFI_HII_HANDLE mTftpHiiHandle;
-
-/*
- Constant strings and definitions related to the message indicating the amount of
- progress in the downloading of a TFTP file.
-*/
-
-// Frame for the progression slider
-STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]";
-
-// Number of steps in the progression slider
-#define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)
-
-// Size in number of characters plus one (final zero) of the message to
-// indicate the progress of a TFTP download. The format is "[(progress slider:
-// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
-// are thus the number of characters in mTftpProgressFrame[] plus 11 characters
-// (2 // spaces, "Kb" and seven characters for the number of KBytes).
-#define TFTP_PROGRESS_MESSAGE_SIZE ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)
-
-// String to delete the TFTP progress message to be able to update it :
-// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'
-STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
-
-// Local File Handle
-SHELL_FILE_HANDLE mFileHandle;
-
-// Path of the local file, Unicode encoded
-CONST CHAR16 *mLocalFilePath;
-
-/**
- Check and convert the UINT16 option values of the 'tftp' command
-
- @param[in] ValueStr Value as an Unicode encoded string
- @param[out] Value UINT16 value
-
- @return TRUE The value was returned.
- @return FALSE A parsing error occurred.
-**/
-STATIC
-BOOLEAN
-StringToUint16 (
- IN CONST CHAR16 *ValueStr,
- OUT UINT16 *Value
- );
-
-/**
- Get the name of the NIC.
-
- @param[in] ControllerHandle The network physical device handle.
- @param[in] NicNumber The network physical device number.
- @param[out] NicName Address where to store the NIC name.
- The memory area has to be at least
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
- double byte wide.
-
- @return EFI_SUCCESS The name of the NIC was returned.
- @return Others The creation of the child for the Managed
- Network Service failed or the opening of
- the Managed Network Protocol failed or
- the operational parameters for the
- Managed Network Protocol could not be
- read.
-**/
-STATIC
-EFI_STATUS
-GetNicName (
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NicNumber,
- OUT CHAR16 *NicName
- );
-
-/**
- Create a child for the service identified by its service binding protocol GUID
- and get from the child the interface of the protocol identified by its GUID.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be created.
- @param[in] ProtocolGuid GUID of the protocol to be open.
- @param[out] ChildHandle Address where the handler of the
- created child is returned. NULL is
- returned in case of error.
- @param[out] Interface Address where a pointer to the
- protocol interface is returned in
- case of success.
-
- @return EFI_SUCCESS The child was created and the protocol opened.
- @return Others Either the creation of the child or the opening
- of the protocol failed.
-**/
-STATIC
-EFI_STATUS
-CreateServiceChildAndOpenProtocol (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- OUT EFI_HANDLE *ChildHandle,
- OUT VOID **Interface
- );
-
-/**
- Close the protocol identified by its GUID on the child handle of the service
- identified by its service binding protocol GUID, then destroy the child
- handle.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be destroyed.
- @param[in] ProtocolGuid GUID of the protocol to be closed.
- @param[in] ChildHandle Handle of the child to be destroyed.
-
-**/
-STATIC
-VOID
-CloseProtocolAndDestroyServiceChild (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- IN EFI_HANDLE ChildHandle
- );
-
-/**
- Worker function that gets the size in numbers of bytes of a file from a TFTP
- server before to download the file.
-
- @param[in] Mtftp4 MTFTP4 protocol interface
- @param[in] FilePath Path of the file, ASCII encoded
- @param[out] FileSize Address where to store the file size in number of
- bytes.
-
- @retval EFI_SUCCESS The size of the file was returned.
- @retval EFI_UNSUPPORTED The server does not support the "tsize" option.
- @retval Others Error when retrieving the information from the server
- (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)
- or error when parsing the response of the server.
-**/
-STATIC
-EFI_STATUS
-GetFileSize (
- IN EFI_MTFTP4_PROTOCOL *Mtftp4,
- IN CONST CHAR8 *FilePath,
- OUT UINTN *FileSize
- );
-
-/**
- Worker function that download the data of a file from a TFTP server given
- the path of the file and its size.
-
- @param[in] Mtftp4 MTFTP4 protocol interface
- @param[in] FilePath Path of the file, Unicode encoded
- @param[in] AsciiFilePath Path of the file, ASCII encoded
- @param[in] FileSize Size of the file in number of bytes
- @param[in] BlockSize Value of the TFTP blksize option
- @param[in] WindowSize Value of the TFTP window size option
-
- @retval EFI_SUCCESS The file was downloaded.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval Others The downloading of the file from the server failed
- (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).
-
-**/
-STATIC
-EFI_STATUS
-DownloadFile (
- IN EFI_MTFTP4_PROTOCOL *Mtftp4,
- IN CONST CHAR16 *FilePath,
- IN CONST CHAR8 *AsciiFilePath,
- IN UINTN FileSize,
- IN UINT16 BlockSize,
- IN UINT16 WindowSize
- );
-
-/**
- Update the progress of a file download
- This procedure is called each time a new TFTP packet is received.
-
- @param[in] This MTFTP4 protocol interface
- @param[in] Token Parameters for the download of the file
- @param[in] PacketLen Length of the packet
- @param[in] Packet Address of the packet
-
- @retval EFI_SUCCESS All packets are accepted.
-
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CheckPacket (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token,
- IN UINT16 PacketLen,
- IN EFI_MTFTP4_PACKET *Packet
- );
-
-EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = {
- TRUE, // Use default setting
- {
- { 0, 0, 0, 0 }
- }, // StationIp - Not relevant as UseDefaultSetting=TRUE
- {
- { 0, 0, 0, 0 }
- }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE
- 0, // LocalPort - Automatically assigned port number.
- {
- { 0, 0, 0, 0 }
- }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE
- {
- { 0, 0, 0, 0 }
- }, // ServerIp - Not known yet
- 69, // InitialServerPort - Standard TFTP server port
- 6, // TryCount - The number of times to transmit request packets and wait for a response.
- 4 // TimeoutValue - Retransmission timeout in seconds.
-};
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-i", TypeValue },
- { L"-l", TypeValue },
- { L"-r", TypeValue },
- { L"-c", TypeValue },
- { L"-t", TypeValue },
- { L"-s", TypeValue },
- { L"-w", TypeValue },
- { NULL, TypeMax }
-};
-
-///
-/// The default block size (512) of tftp is defined in the RFC1350.
-///
-#define MTFTP_DEFAULT_BLKSIZE 512
-///
-/// The valid range of block size option is defined in the RFC2348.
-///
-#define MTFTP_MIN_BLKSIZE 8
-#define MTFTP_MAX_BLKSIZE 65464
-///
-/// The default windowsize (1) of tftp.
-///
-#define MTFTP_DEFAULT_WINDOWSIZE 1
-///
-/// The valid range of window size option.
-/// Note that: RFC 7440 does not mention max window size value, but for the
-/// stability reason, the value is limited to 64.
-///
-#define MTFTP_MIN_WINDOWSIZE 1
-#define MTFTP_MAX_WINDOWSIZE 64
-
-/**
- Function for 'tftp' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @return SHELL_SUCCESS The 'tftp' command completed successfully.
- @return SHELL_ABORTED The Shell Library initialization failed.
- @return SHELL_INVALID_PARAMETER At least one of the command's arguments is
- not valid.
- @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
- @return SHELL_NOT_FOUND Network Interface Card not found or server
- error or file error.
-
-**/
-SHELL_STATUS
-RunTftp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- SHELL_STATUS ShellStatus;
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam;
- UINTN ParamCount;
- CONST CHAR16 *UserNicName;
- BOOLEAN NicFound;
- CONST CHAR16 *ValueStr;
- CONST CHAR16 *RemoteFilePath;
- CHAR8 *AsciiRemoteFilePath;
- UINTN FilePathSize;
- CONST CHAR16 *Walker;
- EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;
- EFI_HANDLE *Handles;
- UINTN HandleCount;
- UINTN NicNumber;
- CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];
- EFI_HANDLE ControllerHandle;
- EFI_HANDLE Mtftp4ChildHandle;
- EFI_MTFTP4_PROTOCOL *Mtftp4;
- UINTN FileSize;
- UINT16 BlockSize;
- UINT16 WindowSize;
-
- ShellStatus = SHELL_INVALID_PARAMETER;
- ProblemParam = NULL;
- NicFound = FALSE;
- AsciiRemoteFilePath = NULL;
- Handles = NULL;
- FileSize = 0;
- BlockSize = MTFTP_DEFAULT_BLKSIZE;
- WindowSize = MTFTP_DEFAULT_WINDOWSIZE;
-
- //
- // Initialize the Shell library (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
-
- //
- // Parse the command line.
- //
- Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) &&
- (ProblemParam != NULL))
- {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PROBLEM),
- mTftpHiiHandle,
- L"tftp",
- ProblemParam
- );
- FreePool (ProblemParam);
- } else {
- ASSERT (FALSE);
- }
-
- goto Error;
- }
-
- //
- // Check the number of parameters
- //
- ParamCount = ShellCommandLineGetCount (CheckPackage);
- if (ParamCount > 4) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_TOO_MANY),
- mTftpHiiHandle,
- L"tftp"
- );
- goto Error;
- }
-
- if (ParamCount < 3) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_TOO_FEW),
- mTftpHiiHandle,
- L"tftp"
- );
- goto Error;
- }
-
- CopyMem (&Mtftp4ConfigData, &DefaultMtftp4ConfigData, sizeof (EFI_MTFTP4_CONFIG_DATA));
-
- //
- // Check the host IPv4 address
- //
- ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
- Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle,
- L"tftp",
- ValueStr
- );
- goto Error;
- }
-
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- ASSERT (RemoteFilePath != NULL);
- FilePathSize = StrLen (RemoteFilePath) + 1;
- AsciiRemoteFilePath = AllocatePool (FilePathSize);
- if (AsciiRemoteFilePath == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Error;
- }
-
- UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);
-
- if (ParamCount == 4) {
- mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
- } else {
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\\') ||
- (*Walker == L'/'))
- {
- break;
- }
- }
-
- mLocalFilePath = Walker + 1;
- }
-
- //
- // Get the name of the Network Interface Card to be used if any.
- //
- UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) {
- goto Error;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) {
- goto Error;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) {
- goto Error;
- }
-
- if (Mtftp4ConfigData.TryCount == 0) {
- Mtftp4ConfigData.TryCount = 6;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {
- goto Error;
- }
-
- if (Mtftp4ConfigData.TimeoutValue == 0) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle,
- L"tftp",
- ValueStr
- );
- goto Error;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &BlockSize)) {
- goto Error;
- }
-
- if ((BlockSize < MTFTP_MIN_BLKSIZE) || (BlockSize > MTFTP_MAX_BLKSIZE)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle,
- L"tftp",
- ValueStr
- );
- goto Error;
- }
- }
-
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w");
- if (ValueStr != NULL) {
- if (!StringToUint16 (ValueStr, &WindowSize)) {
- goto Error;
- }
-
- if ((WindowSize < MTFTP_MIN_WINDOWSIZE) || (WindowSize > MTFTP_MAX_WINDOWSIZE)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle,
- L"tftp",
- ValueStr
- );
- goto Error;
- }
- }
-
- //
- // Locate all MTFTP4 Service Binding protocols
- //
- ShellStatus = SHELL_NOT_FOUND;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- if (EFI_ERROR (Status) || (HandleCount == 0)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_NO_NIC),
- mTftpHiiHandle
- );
- goto Error;
- }
-
- for (NicNumber = 0;
- (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);
- NicNumber++)
- {
- ControllerHandle = Handles[NicNumber];
-
- Status = GetNicName (ControllerHandle, NicNumber, NicName);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),
- mTftpHiiHandle,
- NicNumber,
- Status
- );
- continue;
- }
-
- if (UserNicName != NULL) {
- if (StrCmp (NicName, UserNicName) != 0) {
- continue;
- }
-
- NicFound = TRUE;
- }
-
- Status = CreateServiceChildAndOpenProtocol (
- ControllerHandle,
- &gEfiMtftp4ServiceBindingProtocolGuid,
- &gEfiMtftp4ProtocolGuid,
- &Mtftp4ChildHandle,
- (VOID **)&Mtftp4
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),
- mTftpHiiHandle,
- NicName,
- Status
- );
- continue;
- }
-
- Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),
- mTftpHiiHandle,
- NicName,
- Status
- );
- goto NextHandle;
- }
-
- Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),
- mTftpHiiHandle,
- RemoteFilePath,
- NicName,
- Status
- );
- goto NextHandle;
- }
-
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
- mTftpHiiHandle,
- RemoteFilePath,
- NicName,
- Status
- );
- goto NextHandle;
- }
-
- ShellStatus = SHELL_SUCCESS;
-
-NextHandle:
-
- CloseProtocolAndDestroyServiceChild (
- ControllerHandle,
- &gEfiMtftp4ServiceBindingProtocolGuid,
- &gEfiMtftp4ProtocolGuid,
- Mtftp4ChildHandle
- );
- }
-
- if ((UserNicName != NULL) && (!NicFound)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),
- mTftpHiiHandle,
- UserNicName
- );
- }
-
-Error:
-
- ShellCommandLineFreeVarList (CheckPackage);
- if (AsciiRemoteFilePath != NULL) {
- FreePool (AsciiRemoteFilePath);
- }
-
- if (Handles != NULL) {
- FreePool (Handles);
- }
-
- if ((ShellStatus != SHELL_SUCCESS) && (EFI_ERROR (Status))) {
- ShellStatus = Status & ~MAX_BIT;
- }
-
- return ShellStatus;
-}
-
-/**
- Check and convert the UINT16 option values of the 'tftp' command
-
- @param[in] ValueStr Value as an Unicode encoded string
- @param[out] Value UINT16 value
-
- @return TRUE The value was returned.
- @return FALSE A parsing error occurred.
-**/
-STATIC
-BOOLEAN
-StringToUint16 (
- IN CONST CHAR16 *ValueStr,
- OUT UINT16 *Value
- )
-{
- UINTN Val;
-
- Val = ShellStrToUintn (ValueStr);
- if (Val > MAX_UINT16) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle,
- L"tftp",
- ValueStr
- );
- return FALSE;
- }
-
- *Value = (UINT16)Val;
- return TRUE;
-}
-
-/**
- Get the name of the NIC.
-
- @param[in] ControllerHandle The network physical device handle.
- @param[in] NicNumber The network physical device number.
- @param[out] NicName Address where to store the NIC name.
- The memory area has to be at least
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
- double byte wide.
-
- @return EFI_SUCCESS The name of the NIC was returned.
- @return Others The creation of the child for the Managed
- Network Service failed or the opening of
- the Managed Network Protocol failed or
- the operational parameters for the
- Managed Network Protocol could not be
- read.
-**/
-STATIC
-EFI_STATUS
-GetNicName (
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NicNumber,
- OUT CHAR16 *NicName
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE MnpHandle;
- EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
- EFI_SIMPLE_NETWORK_MODE SnpMode;
-
- Status = CreateServiceChildAndOpenProtocol (
- ControllerHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- &gEfiManagedNetworkProtocolGuid,
- &MnpHandle,
- (VOID **)&Mnp
- );
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
- if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
- goto Error;
- }
-
- UnicodeSPrint (
- NicName,
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
- SnpMode.IfType == NET_IFTYPE_ETHERNET ?
- L"eth%d" :
- L"unk%d",
- NicNumber
- );
-
- Status = EFI_SUCCESS;
-
-Error:
-
- if (MnpHandle != NULL) {
- CloseProtocolAndDestroyServiceChild (
- ControllerHandle,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- &gEfiManagedNetworkProtocolGuid,
- MnpHandle
- );
- }
-
- return Status;
-}
-
-/**
- Create a child for the service identified by its service binding protocol GUID
- and get from the child the interface of the protocol identified by its GUID.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be created.
- @param[in] ProtocolGuid GUID of the protocol to be open.
- @param[out] ChildHandle Address where the handler of the
- created child is returned. NULL is
- returned in case of error.
- @param[out] Interface Address where a pointer to the
- protocol interface is returned in
- case of success.
-
- @return EFI_SUCCESS The child was created and the protocol opened.
- @return Others Either the creation of the child or the opening
- of the protocol failed.
-**/
-STATIC
-EFI_STATUS
-CreateServiceChildAndOpenProtocol (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- OUT EFI_HANDLE *ChildHandle,
- OUT VOID **Interface
- )
-{
- EFI_STATUS Status;
-
- *ChildHandle = NULL;
- Status = NetLibCreateServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- ChildHandle
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- *ChildHandle,
- ProtocolGuid,
- Interface,
- gImageHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- NetLibDestroyServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- *ChildHandle
- );
- *ChildHandle = NULL;
- }
- }
-
- return Status;
-}
-
-/**
- Close the protocol identified by its GUID on the child handle of the service
- identified by its service binding protocol GUID, then destroy the child
- handle.
-
- @param[in] ControllerHandle Controller handle.
- @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
- service to be destroyed.
- @param[in] ProtocolGuid GUID of the protocol to be closed.
- @param[in] ChildHandle Handle of the child to be destroyed.
-
-**/
-STATIC
-VOID
-CloseProtocolAndDestroyServiceChild (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_GUID *ServiceBindingProtocolGuid,
- IN EFI_GUID *ProtocolGuid,
- IN EFI_HANDLE ChildHandle
- )
-{
- gBS->CloseProtocol (
- ChildHandle,
- ProtocolGuid,
- gImageHandle,
- ControllerHandle
- );
-
- NetLibDestroyServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- ChildHandle
- );
-}
-
-/**
- Worker function that gets the size in numbers of bytes of a file from a TFTP
- server before to download the file.
-
- @param[in] Mtftp4 MTFTP4 protocol interface
- @param[in] FilePath Path of the file, ASCII encoded
- @param[out] FileSize Address where to store the file size in number of
- bytes.
-
- @retval EFI_SUCCESS The size of the file was returned.
- @retval EFI_UNSUPPORTED The server does not support the "tsize" option.
- @retval Others Error when retrieving the information from the server
- (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)
- or error when parsing the response of the server.
-**/
-STATIC
-EFI_STATUS
-GetFileSize (
- IN EFI_MTFTP4_PROTOCOL *Mtftp4,
- IN CONST CHAR8 *FilePath,
- OUT UINTN *FileSize
- )
-{
- EFI_STATUS Status;
- EFI_MTFTP4_OPTION ReqOpt[1];
- EFI_MTFTP4_PACKET *Packet;
- UINT32 PktLen;
- EFI_MTFTP4_OPTION *TableOfOptions;
- EFI_MTFTP4_OPTION *Option;
- UINT32 OptCnt;
- UINT8 OptBuf[128];
-
- ReqOpt[0].OptionStr = (UINT8 *)"tsize";
- OptBuf[0] = '0';
- OptBuf[1] = 0;
- ReqOpt[0].ValueStr = OptBuf;
-
- Status = Mtftp4->GetInfo (
- Mtftp4,
- NULL,
- (UINT8 *)FilePath,
- NULL,
- 1,
- ReqOpt,
- &PktLen,
- &Packet
- );
-
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- Status = Mtftp4->ParseOptions (
- Mtftp4,
- PktLen,
- Packet,
- (UINT32 *)&OptCnt,
- &TableOfOptions
- );
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- Option = TableOfOptions;
- while (OptCnt != 0) {
- if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) {
- *FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr);
- break;
- }
-
- OptCnt--;
- Option++;
- }
-
- FreePool (TableOfOptions);
-
- if (OptCnt == 0) {
- Status = EFI_UNSUPPORTED;
- }
-
-Error:
-
- return Status;
-}
-
-/**
- Worker function that download the data of a file from a TFTP server given
- the path of the file and its size.
-
- @param[in] Mtftp4 MTFTP4 protocol interface
- @param[in] FilePath Path of the file, Unicode encoded
- @param[in] AsciiFilePath Path of the file, ASCII encoded
- @param[in] FileSize Size of the file in number of bytes
- @param[in] BlockSize Value of the TFTP blksize option
- @param[in] WindowSize Value of the TFTP window size option
-
- @retval EFI_SUCCESS The file was downloaded.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
- @retval Others The downloading of the file from the server failed
- (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).
-
-**/
-STATIC
-EFI_STATUS
-DownloadFile (
- IN EFI_MTFTP4_PROTOCOL *Mtftp4,
- IN CONST CHAR16 *FilePath,
- IN CONST CHAR8 *AsciiFilePath,
- IN UINTN FileSize,
- IN UINT16 BlockSize,
- IN UINT16 WindowSize
- )
-{
- EFI_STATUS Status;
- DOWNLOAD_CONTEXT *TftpContext;
- EFI_MTFTP4_TOKEN Mtftp4Token;
- UINT8 BlksizeBuf[10];
- UINT8 WindowsizeBuf[10];
-
- ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
-
- TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));
- if (TftpContext == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- TftpContext->FileSize = FileSize;
- TftpContext->DownloadedNbOfBytes = 0;
- TftpContext->LastReportedNbOfBytes = 0;
-
- Mtftp4Token.Filename = (UINT8 *)AsciiFilePath;
- Mtftp4Token.CheckPacket = CheckPacket;
- Mtftp4Token.Context = (VOID *)TftpContext;
- Mtftp4Token.OptionCount = 0;
- Mtftp4Token.OptionList = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);
- if (Mtftp4Token.OptionList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
-
- if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {
- Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"blksize";
- AsciiSPrint ((CHAR8 *)BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize);
- Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = BlksizeBuf;
- Mtftp4Token.OptionCount++;
- }
-
- if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) {
- Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"windowsize";
- AsciiSPrint ((CHAR8 *)WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize);
- Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = WindowsizeBuf;
- Mtftp4Token.OptionCount++;
- }
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_DOWNLOADING),
- mTftpHiiHandle,
- FilePath
- );
-
- //
- // OPEN FILE
- //
- if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
- ShellDeleteFileByName (mLocalFilePath);
- }
-
- Status = ShellOpenFileByName (
- mLocalFilePath,
- &mFileHandle,
- EFI_FILE_MODE_CREATE |
- EFI_FILE_MODE_WRITE |
- EFI_FILE_MODE_READ,
- 0
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
- mTftpHiiHandle,
- L"tftp",
- mLocalFilePath
- );
- goto Error;
- }
-
- Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_CRLF),
- mTftpHiiHandle
- );
-
- //
- // CLOSE FILE
- //
- ShellCloseFile (&mFileHandle);
-
-Error:
- if (TftpContext != NULL) {
- FreePool (TftpContext);
- }
-
- if (Mtftp4Token.OptionList != NULL) {
- FreePool (Mtftp4Token.OptionList);
- }
-
- return Status;
-}
-
-/**
- Update the progress of a file download
- This procedure is called each time a new TFTP packet is received.
-
- @param[in] This MTFTP4 protocol interface
- @param[in] Token Parameters for the download of the file
- @param[in] PacketLen Length of the packet
- @param[in] Packet Address of the packet
-
- @retval EFI_SUCCESS All packets are accepted.
-
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CheckPacket (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token,
- IN UINT16 PacketLen,
- IN EFI_MTFTP4_PACKET *Packet
- )
-{
- DOWNLOAD_CONTEXT *Context;
- CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE];
- UINTN NbOfKb;
- UINTN Index;
- UINTN LastStep;
- UINTN Step;
- UINTN DownloadLen;
- EFI_STATUS Status;
-
- if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {
- return EFI_SUCCESS;
- }
-
- Context = (DOWNLOAD_CONTEXT *)Token->Context;
-
- //
- // The data in the packet are prepended with two UINT16 :
- // . OpCode = EFI_MTFTP4_OPCODE_DATA
- // . Block = the number of this block of data
- //
- DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);
-
- ShellSetFilePosition (mFileHandle, Context->DownloadedNbOfBytes);
- Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data);
- if (EFI_ERROR (Status)) {
- if (Context->DownloadedNbOfBytes > 0) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_CRLF),
- mTftpHiiHandle
- );
- }
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_TFTP_ERR_WRITE),
- mTftpHiiHandle,
- mLocalFilePath,
- Status
- );
- return Status;
- }
-
- if (Context->DownloadedNbOfBytes == 0) {
- ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
- }
-
- Context->DownloadedNbOfBytes += DownloadLen;
- NbOfKb = Context->DownloadedNbOfBytes / 1024;
-
- Progress[0] = L'\0';
- LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
- Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
-
- if (Step <= LastStep) {
- return EFI_SUCCESS;
- }
-
- ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);
-
- Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 1; Index < Step; Index++) {
- Progress[Index] = L'=';
- }
-
- Progress[Step] = L'>';
-
- UnicodeSPrint (
- Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1,
- sizeof (Progress) - sizeof (mTftpProgressFrame),
- L" %7d Kb",
- NbOfKb
- );
- Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;
-
- ShellPrintEx (-1, -1, L"%s", Progress);
-
- return EFI_SUCCESS;
-}
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param ImageHandle The image handle of the process.
-
- @return HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Retrieve HII package list from ImageHandle
- //
- Status = gBS->OpenProtocol (
- ImageHandle,
- &gEfiHiiPackageListProtocolGuid,
- (VOID **)&PackageList,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Publish HII package list to HII Database.
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageList,
- NULL,
- &HiiHandle
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return HiiHandle;
-}
+/** @file + The implementation for the 'tftp' Shell command. + + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Tftp.h" + +#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32 +EFI_HII_HANDLE mTftpHiiHandle; + +/* + Constant strings and definitions related to the message indicating the amount of + progress in the downloading of a TFTP file. +*/ + +// Frame for the progression slider +STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]"; + +// Number of steps in the progression slider +#define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3) + +// Size in number of characters plus one (final zero) of the message to +// indicate the progress of a TFTP download. The format is "[(progress slider: +// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There +// are thus the number of characters in mTftpProgressFrame[] plus 11 characters +// (2 // spaces, "Kb" and seven characters for the number of KBytes). +#define TFTP_PROGRESS_MESSAGE_SIZE ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12) + +// String to delete the TFTP progress message to be able to update it : +// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b' +STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; + +// Local File Handle +SHELL_FILE_HANDLE mFileHandle; + +// Path of the local file, Unicode encoded +CONST CHAR16 *mLocalFilePath; + +/** + Check and convert the UINT16 option values of the 'tftp' command + + @param[in] ValueStr Value as an Unicode encoded string + @param[out] Value UINT16 value + + @return TRUE The value was returned. + @return FALSE A parsing error occurred. +**/ +STATIC +BOOLEAN +StringToUint16 ( + IN CONST CHAR16 *ValueStr, + OUT UINT16 *Value + ); + +/** + Get the name of the NIC. + + @param[in] ControllerHandle The network physical device handle. + @param[in] NicNumber The network physical device number. + @param[out] NicName Address where to store the NIC name. + The memory area has to be at least + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH + double byte wide. + + @return EFI_SUCCESS The name of the NIC was returned. + @return Others The creation of the child for the Managed + Network Service failed or the opening of + the Managed Network Protocol failed or + the operational parameters for the + Managed Network Protocol could not be + read. +**/ +STATIC +EFI_STATUS +GetNicName ( + IN EFI_HANDLE ControllerHandle, + IN UINTN NicNumber, + OUT CHAR16 *NicName + ); + +/** + Create a child for the service identified by its service binding protocol GUID + and get from the child the interface of the protocol identified by its GUID. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be created. + @param[in] ProtocolGuid GUID of the protocol to be open. + @param[out] ChildHandle Address where the handler of the + created child is returned. NULL is + returned in case of error. + @param[out] Interface Address where a pointer to the + protocol interface is returned in + case of success. + + @return EFI_SUCCESS The child was created and the protocol opened. + @return Others Either the creation of the child or the opening + of the protocol failed. +**/ +STATIC +EFI_STATUS +CreateServiceChildAndOpenProtocol ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + OUT EFI_HANDLE *ChildHandle, + OUT VOID **Interface + ); + +/** + Close the protocol identified by its GUID on the child handle of the service + identified by its service binding protocol GUID, then destroy the child + handle. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be destroyed. + @param[in] ProtocolGuid GUID of the protocol to be closed. + @param[in] ChildHandle Handle of the child to be destroyed. + +**/ +STATIC +VOID +CloseProtocolAndDestroyServiceChild ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + IN EFI_HANDLE ChildHandle + ); + +/** + Worker function that gets the size in numbers of bytes of a file from a TFTP + server before to download the file. + + @param[in] Mtftp4 MTFTP4 protocol interface + @param[in] FilePath Path of the file, ASCII encoded + @param[out] FileSize Address where to store the file size in number of + bytes. + + @retval EFI_SUCCESS The size of the file was returned. + @retval EFI_UNSUPPORTED The server does not support the "tsize" option. + @retval Others Error when retrieving the information from the server + (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes) + or error when parsing the response of the server. +**/ +STATIC +EFI_STATUS +GetFileSize ( + IN EFI_MTFTP4_PROTOCOL *Mtftp4, + IN CONST CHAR8 *FilePath, + OUT UINTN *FileSize + ); + +/** + Worker function that download the data of a file from a TFTP server given + the path of the file and its size. + + @param[in] Mtftp4 MTFTP4 protocol interface + @param[in] FilePath Path of the file, Unicode encoded + @param[in] AsciiFilePath Path of the file, ASCII encoded + @param[in] FileSize Size of the file in number of bytes + @param[in] BlockSize Value of the TFTP blksize option + @param[in] WindowSize Value of the TFTP window size option + + @retval EFI_SUCCESS The file was downloaded. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval Others The downloading of the file from the server failed + (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes). + +**/ +STATIC +EFI_STATUS +DownloadFile ( + IN EFI_MTFTP4_PROTOCOL *Mtftp4, + IN CONST CHAR16 *FilePath, + IN CONST CHAR8 *AsciiFilePath, + IN UINTN FileSize, + IN UINT16 BlockSize, + IN UINT16 WindowSize + ); + +/** + Update the progress of a file download + This procedure is called each time a new TFTP packet is received. + + @param[in] This MTFTP4 protocol interface + @param[in] Token Parameters for the download of the file + @param[in] PacketLen Length of the packet + @param[in] Packet Address of the packet + + @retval EFI_SUCCESS All packets are accepted. + +**/ +STATIC +EFI_STATUS +EFIAPI +CheckPacket ( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token, + IN UINT16 PacketLen, + IN EFI_MTFTP4_PACKET *Packet + ); + +EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = { + TRUE, // Use default setting + { + { 0, 0, 0, 0 } + }, // StationIp - Not relevant as UseDefaultSetting=TRUE + { + { 0, 0, 0, 0 } + }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE + 0, // LocalPort - Automatically assigned port number. + { + { 0, 0, 0, 0 } + }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE + { + { 0, 0, 0, 0 } + }, // ServerIp - Not known yet + 69, // InitialServerPort - Standard TFTP server port + 6, // TryCount - The number of times to transmit request packets and wait for a response. + 4 // TimeoutValue - Retransmission timeout in seconds. +}; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-i", TypeValue }, + { L"-l", TypeValue }, + { L"-r", TypeValue }, + { L"-c", TypeValue }, + { L"-t", TypeValue }, + { L"-s", TypeValue }, + { L"-w", TypeValue }, + { NULL, TypeMax } +}; + +/// +/// The default block size (512) of tftp is defined in the RFC1350. +/// +#define MTFTP_DEFAULT_BLKSIZE 512 +/// +/// The valid range of block size option is defined in the RFC2348. +/// +#define MTFTP_MIN_BLKSIZE 8 +#define MTFTP_MAX_BLKSIZE 65464 +/// +/// The default windowsize (1) of tftp. +/// +#define MTFTP_DEFAULT_WINDOWSIZE 1 +/// +/// The valid range of window size option. +/// Note that: RFC 7440 does not mention max window size value, but for the +/// stability reason, the value is limited to 64. +/// +#define MTFTP_MIN_WINDOWSIZE 1 +#define MTFTP_MAX_WINDOWSIZE 64 + +/** + Function for 'tftp' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). + + @return SHELL_SUCCESS The 'tftp' command completed successfully. + @return SHELL_ABORTED The Shell Library initialization failed. + @return SHELL_INVALID_PARAMETER At least one of the command's arguments is + not valid. + @return SHELL_OUT_OF_RESOURCES A memory allocation failed. + @return SHELL_NOT_FOUND Network Interface Card not found or server + error or file error. + +**/ +SHELL_STATUS +RunTftp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + SHELL_STATUS ShellStatus; + EFI_STATUS Status; + LIST_ENTRY *CheckPackage; + CHAR16 *ProblemParam; + UINTN ParamCount; + CONST CHAR16 *UserNicName; + BOOLEAN NicFound; + CONST CHAR16 *ValueStr; + CONST CHAR16 *RemoteFilePath; + CHAR8 *AsciiRemoteFilePath; + UINTN FilePathSize; + CONST CHAR16 *Walker; + EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData; + EFI_HANDLE *Handles; + UINTN HandleCount; + UINTN NicNumber; + CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; + EFI_HANDLE ControllerHandle; + EFI_HANDLE Mtftp4ChildHandle; + EFI_MTFTP4_PROTOCOL *Mtftp4; + UINTN FileSize; + UINT16 BlockSize; + UINT16 WindowSize; + + ShellStatus = SHELL_INVALID_PARAMETER; + ProblemParam = NULL; + NicFound = FALSE; + AsciiRemoteFilePath = NULL; + Handles = NULL; + FileSize = 0; + BlockSize = MTFTP_DEFAULT_BLKSIZE; + WindowSize = MTFTP_DEFAULT_WINDOWSIZE; + + // + // Initialize the Shell library (we must be in non-auto-init...) + // + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + // + // Parse the command line. + // + Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && + (ProblemParam != NULL)) + { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PROBLEM), + mTftpHiiHandle, + L"tftp", + ProblemParam + ); + FreePool (ProblemParam); + } else { + ASSERT (FALSE); + } + + goto Error; + } + + // + // Check the number of parameters + // + ParamCount = ShellCommandLineGetCount (CheckPackage); + if (ParamCount > 4) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_TOO_MANY), + mTftpHiiHandle, + L"tftp" + ); + goto Error; + } + + if (ParamCount < 3) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_TOO_FEW), + mTftpHiiHandle, + L"tftp" + ); + goto Error; + } + + CopyMem (&Mtftp4ConfigData, &DefaultMtftp4ConfigData, sizeof (EFI_MTFTP4_CONFIG_DATA)); + + // + // Check the host IPv4 address + // + ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); + Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PARAM_INV), + mTftpHiiHandle, + L"tftp", + ValueStr + ); + goto Error; + } + + RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); + ASSERT (RemoteFilePath != NULL); + FilePathSize = StrLen (RemoteFilePath) + 1; + AsciiRemoteFilePath = AllocatePool (FilePathSize); + if (AsciiRemoteFilePath == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Error; + } + + UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize); + + if (ParamCount == 4) { + mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3); + } else { + Walker = RemoteFilePath + StrLen (RemoteFilePath); + while ((--Walker) >= RemoteFilePath) { + if ((*Walker == L'\\') || + (*Walker == L'/')) + { + break; + } + } + + mLocalFilePath = Walker + 1; + } + + // + // Get the name of the Network Interface Card to be used if any. + // + UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i"); + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) { + goto Error; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) { + goto Error; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) { + goto Error; + } + + if (Mtftp4ConfigData.TryCount == 0) { + Mtftp4ConfigData.TryCount = 6; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) { + goto Error; + } + + if (Mtftp4ConfigData.TimeoutValue == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PARAM_INV), + mTftpHiiHandle, + L"tftp", + ValueStr + ); + goto Error; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &BlockSize)) { + goto Error; + } + + if ((BlockSize < MTFTP_MIN_BLKSIZE) || (BlockSize > MTFTP_MAX_BLKSIZE)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PARAM_INV), + mTftpHiiHandle, + L"tftp", + ValueStr + ); + goto Error; + } + } + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w"); + if (ValueStr != NULL) { + if (!StringToUint16 (ValueStr, &WindowSize)) { + goto Error; + } + + if ((WindowSize < MTFTP_MIN_WINDOWSIZE) || (WindowSize > MTFTP_MAX_WINDOWSIZE)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PARAM_INV), + mTftpHiiHandle, + L"tftp", + ValueStr + ); + goto Error; + } + } + + // + // Locate all MTFTP4 Service Binding protocols + // + ShellStatus = SHELL_NOT_FOUND; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiManagedNetworkServiceBindingProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + if (EFI_ERROR (Status) || (HandleCount == 0)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_NO_NIC), + mTftpHiiHandle + ); + goto Error; + } + + for (NicNumber = 0; + (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS); + NicNumber++) + { + ControllerHandle = Handles[NicNumber]; + + Status = GetNicName (ControllerHandle, NicNumber, NicName); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_NIC_NAME), + mTftpHiiHandle, + NicNumber, + Status + ); + continue; + } + + if (UserNicName != NULL) { + if (StrCmp (NicName, UserNicName) != 0) { + continue; + } + + NicFound = TRUE; + } + + Status = CreateServiceChildAndOpenProtocol ( + ControllerHandle, + &gEfiMtftp4ServiceBindingProtocolGuid, + &gEfiMtftp4ProtocolGuid, + &Mtftp4ChildHandle, + (VOID **)&Mtftp4 + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL), + mTftpHiiHandle, + NicName, + Status + ); + continue; + } + + Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_CONFIGURE), + mTftpHiiHandle, + NicName, + Status + ); + goto NextHandle; + } + + Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE), + mTftpHiiHandle, + RemoteFilePath, + NicName, + Status + ); + goto NextHandle; + } + + Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD), + mTftpHiiHandle, + RemoteFilePath, + NicName, + Status + ); + goto NextHandle; + } + + ShellStatus = SHELL_SUCCESS; + +NextHandle: + + CloseProtocolAndDestroyServiceChild ( + ControllerHandle, + &gEfiMtftp4ServiceBindingProtocolGuid, + &gEfiMtftp4ProtocolGuid, + Mtftp4ChildHandle + ); + } + + if ((UserNicName != NULL) && (!NicFound)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND), + mTftpHiiHandle, + UserNicName + ); + } + +Error: + + ShellCommandLineFreeVarList (CheckPackage); + if (AsciiRemoteFilePath != NULL) { + FreePool (AsciiRemoteFilePath); + } + + if (Handles != NULL) { + FreePool (Handles); + } + + if ((ShellStatus != SHELL_SUCCESS) && (EFI_ERROR (Status))) { + ShellStatus = Status & ~MAX_BIT; + } + + return ShellStatus; +} + +/** + Check and convert the UINT16 option values of the 'tftp' command + + @param[in] ValueStr Value as an Unicode encoded string + @param[out] Value UINT16 value + + @return TRUE The value was returned. + @return FALSE A parsing error occurred. +**/ +STATIC +BOOLEAN +StringToUint16 ( + IN CONST CHAR16 *ValueStr, + OUT UINT16 *Value + ) +{ + UINTN Val; + + Val = ShellStrToUintn (ValueStr); + if (Val > MAX_UINT16) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_PARAM_INV), + mTftpHiiHandle, + L"tftp", + ValueStr + ); + return FALSE; + } + + *Value = (UINT16)Val; + return TRUE; +} + +/** + Get the name of the NIC. + + @param[in] ControllerHandle The network physical device handle. + @param[in] NicNumber The network physical device number. + @param[out] NicName Address where to store the NIC name. + The memory area has to be at least + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH + double byte wide. + + @return EFI_SUCCESS The name of the NIC was returned. + @return Others The creation of the child for the Managed + Network Service failed or the opening of + the Managed Network Protocol failed or + the operational parameters for the + Managed Network Protocol could not be + read. +**/ +STATIC +EFI_STATUS +GetNicName ( + IN EFI_HANDLE ControllerHandle, + IN UINTN NicNumber, + OUT CHAR16 *NicName + ) +{ + EFI_STATUS Status; + EFI_HANDLE MnpHandle; + EFI_MANAGED_NETWORK_PROTOCOL *Mnp; + EFI_SIMPLE_NETWORK_MODE SnpMode; + + Status = CreateServiceChildAndOpenProtocol ( + ControllerHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid, + &gEfiManagedNetworkProtocolGuid, + &MnpHandle, + (VOID **)&Mnp + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = Mnp->GetModeData (Mnp, NULL, &SnpMode); + if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) { + goto Error; + } + + UnicodeSPrint ( + NicName, + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH, + SnpMode.IfType == NET_IFTYPE_ETHERNET ? + L"eth%d" : + L"unk%d", + NicNumber + ); + + Status = EFI_SUCCESS; + +Error: + + if (MnpHandle != NULL) { + CloseProtocolAndDestroyServiceChild ( + ControllerHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid, + &gEfiManagedNetworkProtocolGuid, + MnpHandle + ); + } + + return Status; +} + +/** + Create a child for the service identified by its service binding protocol GUID + and get from the child the interface of the protocol identified by its GUID. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be created. + @param[in] ProtocolGuid GUID of the protocol to be open. + @param[out] ChildHandle Address where the handler of the + created child is returned. NULL is + returned in case of error. + @param[out] Interface Address where a pointer to the + protocol interface is returned in + case of success. + + @return EFI_SUCCESS The child was created and the protocol opened. + @return Others Either the creation of the child or the opening + of the protocol failed. +**/ +STATIC +EFI_STATUS +CreateServiceChildAndOpenProtocol ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + OUT EFI_HANDLE *ChildHandle, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + *ChildHandle = NULL; + Status = NetLibCreateServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + ChildHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + *ChildHandle, + ProtocolGuid, + Interface, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + NetLibDestroyServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + *ChildHandle + ); + *ChildHandle = NULL; + } + } + + return Status; +} + +/** + Close the protocol identified by its GUID on the child handle of the service + identified by its service binding protocol GUID, then destroy the child + handle. + + @param[in] ControllerHandle Controller handle. + @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the + service to be destroyed. + @param[in] ProtocolGuid GUID of the protocol to be closed. + @param[in] ChildHandle Handle of the child to be destroyed. + +**/ +STATIC +VOID +CloseProtocolAndDestroyServiceChild ( + IN EFI_HANDLE ControllerHandle, + IN EFI_GUID *ServiceBindingProtocolGuid, + IN EFI_GUID *ProtocolGuid, + IN EFI_HANDLE ChildHandle + ) +{ + gBS->CloseProtocol ( + ChildHandle, + ProtocolGuid, + gImageHandle, + ControllerHandle + ); + + NetLibDestroyServiceChild ( + ControllerHandle, + gImageHandle, + ServiceBindingProtocolGuid, + ChildHandle + ); +} + +/** + Worker function that gets the size in numbers of bytes of a file from a TFTP + server before to download the file. + + @param[in] Mtftp4 MTFTP4 protocol interface + @param[in] FilePath Path of the file, ASCII encoded + @param[out] FileSize Address where to store the file size in number of + bytes. + + @retval EFI_SUCCESS The size of the file was returned. + @retval EFI_UNSUPPORTED The server does not support the "tsize" option. + @retval Others Error when retrieving the information from the server + (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes) + or error when parsing the response of the server. +**/ +STATIC +EFI_STATUS +GetFileSize ( + IN EFI_MTFTP4_PROTOCOL *Mtftp4, + IN CONST CHAR8 *FilePath, + OUT UINTN *FileSize + ) +{ + EFI_STATUS Status; + EFI_MTFTP4_OPTION ReqOpt[1]; + EFI_MTFTP4_PACKET *Packet; + UINT32 PktLen; + EFI_MTFTP4_OPTION *TableOfOptions; + EFI_MTFTP4_OPTION *Option; + UINT32 OptCnt; + UINT8 OptBuf[128]; + + ReqOpt[0].OptionStr = (UINT8 *)"tsize"; + OptBuf[0] = '0'; + OptBuf[1] = 0; + ReqOpt[0].ValueStr = OptBuf; + + Status = Mtftp4->GetInfo ( + Mtftp4, + NULL, + (UINT8 *)FilePath, + NULL, + 1, + ReqOpt, + &PktLen, + &Packet + ); + + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = Mtftp4->ParseOptions ( + Mtftp4, + PktLen, + Packet, + (UINT32 *)&OptCnt, + &TableOfOptions + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + Option = TableOfOptions; + while (OptCnt != 0) { + if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) { + *FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr); + break; + } + + OptCnt--; + Option++; + } + + FreePool (TableOfOptions); + + if (OptCnt == 0) { + Status = EFI_UNSUPPORTED; + } + +Error: + + return Status; +} + +/** + Worker function that download the data of a file from a TFTP server given + the path of the file and its size. + + @param[in] Mtftp4 MTFTP4 protocol interface + @param[in] FilePath Path of the file, Unicode encoded + @param[in] AsciiFilePath Path of the file, ASCII encoded + @param[in] FileSize Size of the file in number of bytes + @param[in] BlockSize Value of the TFTP blksize option + @param[in] WindowSize Value of the TFTP window size option + + @retval EFI_SUCCESS The file was downloaded. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval Others The downloading of the file from the server failed + (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes). + +**/ +STATIC +EFI_STATUS +DownloadFile ( + IN EFI_MTFTP4_PROTOCOL *Mtftp4, + IN CONST CHAR16 *FilePath, + IN CONST CHAR8 *AsciiFilePath, + IN UINTN FileSize, + IN UINT16 BlockSize, + IN UINT16 WindowSize + ) +{ + EFI_STATUS Status; + DOWNLOAD_CONTEXT *TftpContext; + EFI_MTFTP4_TOKEN Mtftp4Token; + UINT8 BlksizeBuf[10]; + UINT8 WindowsizeBuf[10]; + + ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN)); + + TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT)); + if (TftpContext == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + TftpContext->FileSize = FileSize; + TftpContext->DownloadedNbOfBytes = 0; + TftpContext->LastReportedNbOfBytes = 0; + + Mtftp4Token.Filename = (UINT8 *)AsciiFilePath; + Mtftp4Token.CheckPacket = CheckPacket; + Mtftp4Token.Context = (VOID *)TftpContext; + Mtftp4Token.OptionCount = 0; + Mtftp4Token.OptionList = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2); + if (Mtftp4Token.OptionList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + if (BlockSize != MTFTP_DEFAULT_BLKSIZE) { + Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"blksize"; + AsciiSPrint ((CHAR8 *)BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize); + Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = BlksizeBuf; + Mtftp4Token.OptionCount++; + } + + if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) { + Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"windowsize"; + AsciiSPrint ((CHAR8 *)WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize); + Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = WindowsizeBuf; + Mtftp4Token.OptionCount++; + } + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_DOWNLOADING), + mTftpHiiHandle, + FilePath + ); + + // + // OPEN FILE + // + if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) { + ShellDeleteFileByName (mLocalFilePath); + } + + Status = ShellOpenFileByName ( + mLocalFilePath, + &mFileHandle, + EFI_FILE_MODE_CREATE | + EFI_FILE_MODE_WRITE | + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), + mTftpHiiHandle, + L"tftp", + mLocalFilePath + ); + goto Error; + } + + Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_CRLF), + mTftpHiiHandle + ); + + // + // CLOSE FILE + // + ShellCloseFile (&mFileHandle); + +Error: + if (TftpContext != NULL) { + FreePool (TftpContext); + } + + if (Mtftp4Token.OptionList != NULL) { + FreePool (Mtftp4Token.OptionList); + } + + return Status; +} + +/** + Update the progress of a file download + This procedure is called each time a new TFTP packet is received. + + @param[in] This MTFTP4 protocol interface + @param[in] Token Parameters for the download of the file + @param[in] PacketLen Length of the packet + @param[in] Packet Address of the packet + + @retval EFI_SUCCESS All packets are accepted. + +**/ +STATIC +EFI_STATUS +EFIAPI +CheckPacket ( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token, + IN UINT16 PacketLen, + IN EFI_MTFTP4_PACKET *Packet + ) +{ + DOWNLOAD_CONTEXT *Context; + CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE]; + UINTN NbOfKb; + UINTN Index; + UINTN LastStep; + UINTN Step; + UINTN DownloadLen; + EFI_STATUS Status; + + if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) { + return EFI_SUCCESS; + } + + Context = (DOWNLOAD_CONTEXT *)Token->Context; + + // + // The data in the packet are prepended with two UINT16 : + // . OpCode = EFI_MTFTP4_OPCODE_DATA + // . Block = the number of this block of data + // + DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block); + + ShellSetFilePosition (mFileHandle, Context->DownloadedNbOfBytes); + Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data); + if (EFI_ERROR (Status)) { + if (Context->DownloadedNbOfBytes > 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_CRLF), + mTftpHiiHandle + ); + } + + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_TFTP_ERR_WRITE), + mTftpHiiHandle, + mLocalFilePath, + Status + ); + return Status; + } + + if (Context->DownloadedNbOfBytes == 0) { + ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame); + } + + Context->DownloadedNbOfBytes += DownloadLen; + NbOfKb = Context->DownloadedNbOfBytes / 1024; + + Progress[0] = L'\0'; + LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize; + Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize; + + if (Step <= LastStep) { + return EFI_SUCCESS; + } + + ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete); + + Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 1; Index < Step; Index++) { + Progress[Index] = L'='; + } + + Progress[Step] = L'>'; + + UnicodeSPrint ( + Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1, + sizeof (Progress) - sizeof (mTftpProgressFrame), + L" %7d Kb", + NbOfKb + ); + Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes; + + ShellPrintEx (-1, -1, L"%s", Progress); + + return EFI_SUCCESS; +} + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param ImageHandle The image handle of the process. + + @return HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + EFI_HII_HANDLE HiiHandle; + + // + // Retrieve HII package list from ImageHandle + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **)&PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + // + // Publish HII package list to HII Database. + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &HiiHandle + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + return HiiHandle; +} diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.h b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.h index 89cb79c335..b64c145d68 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.h +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.h @@ -1,70 +1,70 @@ -/** @file
- Header file for 'tftp' command functions.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _TFTP_H_
-#define _TFTP_H_
-
-#include <Uefi.h>
-
-#include <Protocol/HiiPackageList.h>
-#include <Protocol/ServiceBinding.h>
-#include <Protocol/Mtftp4.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/HiiLib.h>
-#include <Library/NetLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiHiiServicesLib.h>
-
-extern EFI_HII_HANDLE mTftpHiiHandle;
-
-typedef struct {
- UINTN FileSize;
- UINTN DownloadedNbOfBytes;
- UINTN LastReportedNbOfBytes;
-} DOWNLOAD_CONTEXT;
-
-/**
- Function for 'tftp' command.
-
- @param[in] ImageHandle The image handle.
- @param[in] SystemTable The system table.
-
- @retval SHELL_SUCCESS Command completed successfully.
- @retval SHELL_INVALID_PARAMETER Command usage error.
- @retval SHELL_ABORTED The user aborts the operation.
- @retval value Unknown error.
-**/
-SHELL_STATUS
-RunTftp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param ImageHandle The image handle of the process.
-
- @return HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- EFI_HANDLE ImageHandle
- );
-
-#endif // _TFTP_H_
+/** @file + Header file for 'tftp' command functions. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _TFTP_H_ +#define _TFTP_H_ + +#include <Uefi.h> + +#include <Protocol/HiiPackageList.h> +#include <Protocol/ServiceBinding.h> +#include <Protocol/Mtftp4.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/HiiLib.h> +#include <Library/NetLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiHiiServicesLib.h> + +extern EFI_HII_HANDLE mTftpHiiHandle; + +typedef struct { + UINTN FileSize; + UINTN DownloadedNbOfBytes; + UINTN LastReportedNbOfBytes; +} DOWNLOAD_CONTEXT; + +/** + Function for 'tftp' command. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval SHELL_SUCCESS Command completed successfully. + @retval SHELL_INVALID_PARAMETER Command usage error. + @retval SHELL_ABORTED The user aborts the operation. + @retval value Unknown error. +**/ +SHELL_STATUS +RunTftp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param ImageHandle The image handle of the process. + + @return HII handle. +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + EFI_HANDLE ImageHandle + ); + +#endif // _TFTP_H_ diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.uni b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.uni index ebac9c6c93..33170d784e 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.uni +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.uni @@ -1,94 +1,94 @@ -// /**
-//
-// (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
-// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Module Name:
-//
-// Tftp.uni
-//
-// Abstract:
-//
-// String definitions for UEFI Shell TFTP command
-//
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments\r\n"
-#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments\r\n"
-#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n"
-#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
-#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
-#string STR_GEN_CRLF #language en-US "\r\n"
-
-#string STR_TFTP_ERR_NO_NIC #language en-US "No network interface card found.\r\n"
-#string STR_TFTP_ERR_NIC_NAME #language en-US "Failed to get the name of the network interface card number %d - %r\r\n"
-#string STR_TFTP_ERR_OPEN_PROTOCOL #language en-US "Unable to open MTFTP4 protocol on '%H%s%N' - %r\r\n"
-#string STR_TFTP_ERR_CONFIGURE #language en-US "Unable to configure MTFTP4 protocol on '%H%s%N' - %r\r\n"
-#string STR_TFTP_ERR_FILE_SIZE #language en-US "Unable to get the size of the file '%H%s%N' on '%H%s%N' - %r\r\n"
-#string STR_TFTP_ERR_DOWNLOAD #language en-US "Unable to download the file '%H%s%N' on '%H%s%N' - %r\r\n"
-#string STR_TFTP_ERR_WRITE #language en-US "Unable to write into file '%H%s%N' - %r\r\n"
-#string STR_TFTP_ERR_NIC_NOT_FOUND #language en-US "Network Interface Card '%H%s%N' not found.\r\n"
-#string STR_TFTP_DOWNLOADING #language en-US "Downloading the file '%H%s%N'\r\n"
-#string STR_TFTP_STRING #language en-US "%s"
-
-#string STR_GET_HELP_TFTP #language en-US ""
-".TH tftp 0 "Download a file from TFTP server."\r\n"
-".SH NAME\r\n"
-"Download a file from TFTP server.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"TFTP [-i interface] [-l <port>] [-r <port>] [-c <retry count>] [-t <timeout>]\r\n"
-" [-s <block size>] [-w <window size>] host remotefilepath [localfilepath]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -i interface - Specifies an adapter name, i.e., eth0.\r\n"
-" -l port - Specifies the local port number. Default value is 0\r\n"
-" and the port number is automatically assigned.\r\n"
-" -r port - Specifies the remote port number. Default value is 69.\r\n"
-" -c <retry count> - The number of times to transmit request packets and\r\n"
-" wait for a response. The default value is 6. Set to zero\r\n"
-" also means to use the default value.\r\n"
-" -t <timeout> - The number of seconds to wait for a response after\r\n"
-" sending a request packet. Default value is 4s.\r\n"
-" -s <block size> - Specifies the TFTP blksize option as defined in RFC 2348.\r\n"
-" Valid range is between 8 and 65464, default value is 512.\r\n"
-" -w <window size> - Specifies the TFTP windowsize option as defined in RFC 7440.\r\n"
-" Valid range is between 1 and 64, default value is 1.\r\n"
-" host - Specify TFTP Server IPv4 address.\r\n"
-" remotefilepath - TFTP server file path to download the file.\r\n"
-" localfilepath - Local destination file path.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. The TFTP command allows to get the file specified by its 'remotefilepath'\r\n"
-" path from the TFTP server specified by its 'host' IPv4 address. If the\r\n"
-" optional 'localfilepath' parameter is provided, the downloaded file is\r\n"
-" stored locally using the provided file path. If the local file path is\r\n"
-" not specified, the file is stored in the current directory using the file\r\n"
-" server's name.\r\n"
-" 2. Before using the TFTP command, the network interface intended to be\r\n"
-" used to retrieve the file must be configured. This configuration may be\r\n"
-" done by means of the 'ifconfig' command.\r\n"
-" 3. If a network interface is defined with the '-i' option then only this\r\n"
-" interface will be used to retrieve the remote file. Otherwise, all network\r\n"
-" interfaces are tried in the order they have been discovered during the\r\n"
-" DXE phase.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To get the file "dir1/file1.dat" from the TFTP server 192.168.1.1 and\r\n"
-" store it as file2.dat in the current directory :\r\n"
-" fs0:\> tftp 192.168.1.1 dir1/file1.dat file2.dat\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-
+// /** +// +// (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR> +// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// Tftp.uni +// +// Abstract: +// +// String definitions for UEFI Shell TFTP command +// +// +// **/ + +/=# + +#langdef en-US "english" + +#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments\r\n" +#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments\r\n" +#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n" +#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n" +#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n" +#string STR_GEN_CRLF #language en-US "\r\n" + +#string STR_TFTP_ERR_NO_NIC #language en-US "No network interface card found.\r\n" +#string STR_TFTP_ERR_NIC_NAME #language en-US "Failed to get the name of the network interface card number %d - %r\r\n" +#string STR_TFTP_ERR_OPEN_PROTOCOL #language en-US "Unable to open MTFTP4 protocol on '%H%s%N' - %r\r\n" +#string STR_TFTP_ERR_CONFIGURE #language en-US "Unable to configure MTFTP4 protocol on '%H%s%N' - %r\r\n" +#string STR_TFTP_ERR_FILE_SIZE #language en-US "Unable to get the size of the file '%H%s%N' on '%H%s%N' - %r\r\n" +#string STR_TFTP_ERR_DOWNLOAD #language en-US "Unable to download the file '%H%s%N' on '%H%s%N' - %r\r\n" +#string STR_TFTP_ERR_WRITE #language en-US "Unable to write into file '%H%s%N' - %r\r\n" +#string STR_TFTP_ERR_NIC_NOT_FOUND #language en-US "Network Interface Card '%H%s%N' not found.\r\n" +#string STR_TFTP_DOWNLOADING #language en-US "Downloading the file '%H%s%N'\r\n" +#string STR_TFTP_STRING #language en-US "%s" + +#string STR_GET_HELP_TFTP #language en-US "" +".TH tftp 0 "Download a file from TFTP server."\r\n" +".SH NAME\r\n" +"Download a file from TFTP server.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"TFTP [-i interface] [-l <port>] [-r <port>] [-c <retry count>] [-t <timeout>]\r\n" +" [-s <block size>] [-w <window size>] host remotefilepath [localfilepath]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -i interface - Specifies an adapter name, i.e., eth0.\r\n" +" -l port - Specifies the local port number. Default value is 0\r\n" +" and the port number is automatically assigned.\r\n" +" -r port - Specifies the remote port number. Default value is 69.\r\n" +" -c <retry count> - The number of times to transmit request packets and\r\n" +" wait for a response. The default value is 6. Set to zero\r\n" +" also means to use the default value.\r\n" +" -t <timeout> - The number of seconds to wait for a response after\r\n" +" sending a request packet. Default value is 4s.\r\n" +" -s <block size> - Specifies the TFTP blksize option as defined in RFC 2348.\r\n" +" Valid range is between 8 and 65464, default value is 512.\r\n" +" -w <window size> - Specifies the TFTP windowsize option as defined in RFC 7440.\r\n" +" Valid range is between 1 and 64, default value is 1.\r\n" +" host - Specify TFTP Server IPv4 address.\r\n" +" remotefilepath - TFTP server file path to download the file.\r\n" +" localfilepath - Local destination file path.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +"NOTES:\r\n" +" 1. The TFTP command allows to get the file specified by its 'remotefilepath'\r\n" +" path from the TFTP server specified by its 'host' IPv4 address. If the\r\n" +" optional 'localfilepath' parameter is provided, the downloaded file is\r\n" +" stored locally using the provided file path. If the local file path is\r\n" +" not specified, the file is stored in the current directory using the file\r\n" +" server's name.\r\n" +" 2. Before using the TFTP command, the network interface intended to be\r\n" +" used to retrieve the file must be configured. This configuration may be\r\n" +" done by means of the 'ifconfig' command.\r\n" +" 3. If a network interface is defined with the '-i' option then only this\r\n" +" interface will be used to retrieve the remote file. Otherwise, all network\r\n" +" interfaces are tried in the order they have been discovered during the\r\n" +" DXE phase.\r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To get the file "dir1/file1.dat" from the TFTP server 192.168.1.1 and\r\n" +" store it as file2.dat in the current directory :\r\n" +" fs0:\> tftp 192.168.1.1 dir1/file1.dat file2.dat\r\n" +".SH RETURNVALUES\r\n" +" \r\n" +"RETURN VALUES:\r\n" +" SHELL_SUCCESS The action was completed as requested.\r\n" +" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n" +" formatted or its value was out of bounds.\r\n" + diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.c index 5af7784cff..c70239a0a1 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.c +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.c @@ -1,49 +1,49 @@ -/** @file
- Entrypoint of "tftp" shell standalone application.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "Tftp.h"
-
-//
-// String token ID of help message text.
-// Shell supports to find help message in the resource section of an application image if
-// .MAN file is not found. This global variable is added to make build tool recognizes
-// that the help string is consumed by user and then build tool will add the string into
-// the resource section. Thus the application can use '-?' option to show help message in
-// Shell.
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_TFTP);
-
-/**
- Entry point of Tftp standalone application.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Tftp command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing tftp command.
-**/
-EFI_STATUS
-EFIAPI
-TftpAppInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mTftpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mTftpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = (EFI_STATUS)RunTftp (ImageHandle, SystemTable);
- HiiRemovePackages (mTftpHiiHandle);
- return Status;
-}
+/** @file + Entrypoint of "tftp" shell standalone application. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "Tftp.h" + +// +// String token ID of help message text. +// Shell supports to find help message in the resource section of an application image if +// .MAN file is not found. This global variable is added to make build tool recognizes +// that the help string is consumed by user and then build tool will add the string into +// the resource section. Thus the application can use '-?' option to show help message in +// Shell. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_TFTP); + +/** + Entry point of Tftp standalone application. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Tftp command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing tftp command. +**/ +EFI_STATUS +EFIAPI +TftpAppInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mTftpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mTftpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = (EFI_STATUS)RunTftp (ImageHandle, SystemTable); + HiiRemovePackages (mTftpHiiHandle); + return Status; +} diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf index bc13c89a97..4eb02f8670 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf @@ -1,55 +1,55 @@ -## @file
-# Provides Shell 'tftp' standalone application.
-#
-# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
-# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = tftp
- FILE_GUID = 8DC58D0D-67F5-4B97-9DFC-E442BB9A5648
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- ENTRY_POINT = TftpAppInitialize
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Tftp.uni
- Tftp.h
- Tftp.c
- TftpApp.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- NetworkPkg/NetworkPkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- UefiApplicationEntryPoint
- UefiHiiServicesLib
- HiiLib
- FileHandleLib
- NetLib
-
-[Protocols]
- gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
- gEfiMtftp4ServiceBindingProtocolGuid ## CONSUMES
- gEfiMtftp4ProtocolGuid ## CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
+## @file +# Provides Shell 'tftp' standalone application. +# +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR> +# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = tftp + FILE_GUID = 8DC58D0D-67F5-4B97-9DFC-E442BB9A5648 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = TftpAppInitialize +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Tftp.uni + Tftp.h + Tftp.c + TftpApp.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + UefiApplicationEntryPoint + UefiHiiServicesLib + HiiLib + FileHandleLib + NetLib + +[Protocols] + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES + gEfiMtftp4ServiceBindingProtocolGuid ## CONSUMES + gEfiMtftp4ProtocolGuid ## CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.c index 23c86a785c..22110ed057 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.c +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.c @@ -1,129 +1,129 @@ -/** @file
- Produce "tftp" shell dynamic command.
-
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "Tftp.h"
-#include <Protocol/ShellDynamicCommand.h>
-
-/**
- This is the shell command handler function pointer callback type. This
- function handles the command when it is invoked in the shell.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] SystemTable The pointer to the system table.
- @param[in] ShellParameters The parameters associated with the command.
- @param[in] Shell The instance of the shell protocol used in the context
- of processing this command.
-
- @return EFI_SUCCESS the operation was successful
- @return other the operation failed.
-**/
-SHELL_STATUS
-EFIAPI
-TftpCommandHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- )
-{
- gEfiShellParametersProtocol = ShellParameters;
- gEfiShellProtocol = Shell;
- return RunTftp (gImageHandle, SystemTable);
-}
-
-/**
- This is the command help handler function pointer callback type. This
- function is responsible for displaying help information for the associated
- command.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] Language The pointer to the language string to use.
-
- @return string Pool allocated help string, must be freed by caller
-**/
-CHAR16 *
-EFIAPI
-TftpCommandGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- )
-{
- return HiiGetString (mTftpHiiHandle, STRING_TOKEN (STR_GET_HELP_TFTP), Language);
-}
-
-EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mTftpDynamicCommand = {
- L"tftp",
- TftpCommandHandler,
- TftpCommandGetHelp
-};
-
-/**
- Entry point of Tftp Dynamic Command.
-
- Produce the DynamicCommand protocol to handle "tftp" command.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS Tftp command is executed successfully.
- @retval EFI_ABORTED HII package was failed to initialize.
- @retval others Other errors when executing tftp command.
-**/
-EFI_STATUS
-EFIAPI
-TftpCommandInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mTftpHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mTftpHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mTftpDynamicCommand
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
-/**
- Tftp driver unload handler.
-
- @param ImageHandle The image handle of the process.
-
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
-**/
-EFI_STATUS
-EFIAPI
-TftpUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- Status = gBS->UninstallProtocolInterface (
- ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- &mTftpDynamicCommand
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HiiRemovePackages (mTftpHiiHandle);
- return EFI_SUCCESS;
-}
+/** @file + Produce "tftp" shell dynamic command. + + Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR> + Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "Tftp.h" +#include <Protocol/ShellDynamicCommand.h> + +/** + This is the shell command handler function pointer callback type. This + function handles the command when it is invoked in the shell. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] SystemTable The pointer to the system table. + @param[in] ShellParameters The parameters associated with the command. + @param[in] Shell The instance of the shell protocol used in the context + of processing this command. + + @return EFI_SUCCESS the operation was successful + @return other the operation failed. +**/ +SHELL_STATUS +EFIAPI +TftpCommandHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + gEfiShellParametersProtocol = ShellParameters; + gEfiShellProtocol = Shell; + return RunTftp (gImageHandle, SystemTable); +} + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed by caller +**/ +CHAR16 * +EFIAPI +TftpCommandGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + return HiiGetString (mTftpHiiHandle, STRING_TOKEN (STR_GET_HELP_TFTP), Language); +} + +EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mTftpDynamicCommand = { + L"tftp", + TftpCommandHandler, + TftpCommandGetHelp +}; + +/** + Entry point of Tftp Dynamic Command. + + Produce the DynamicCommand protocol to handle "tftp" command. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS Tftp command is executed successfully. + @retval EFI_ABORTED HII package was failed to initialize. + @retval others Other errors when executing tftp command. +**/ +EFI_STATUS +EFIAPI +TftpCommandInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mTftpHiiHandle = InitializeHiiPackage (ImageHandle); + if (mTftpHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + EFI_NATIVE_INTERFACE, + &mTftpDynamicCommand + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Tftp driver unload handler. + + @param ImageHandle The image handle of the process. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. +**/ +EFI_STATUS +EFIAPI +TftpUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status = gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mTftpDynamicCommand + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiRemovePackages (mTftpHiiHandle); + return EFI_SUCCESS; +} diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf index b0c8e8f84b..695af5559a 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf @@ -1,60 +1,60 @@ -## @file
-# Provides Shell 'tftp' dynamic command.
-#
-# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
-# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = tftpDynamicCommand
- FILE_GUID = A487A478-51EF-48AA-8794-7BEE2A0562F1
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = TftpCommandInitialize
- UNLOAD_IMAGE = TftpUnload
-#
-# This flag specifies whether HII resource section is generated into PE image.
-#
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- Tftp.uni
- Tftp.h
- Tftp.c
- TftpDynamicCommand.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- NetworkPkg/NetworkPkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiHiiServicesLib
- HiiLib
- FileHandleLib
- NetLib
-
-[Protocols]
- gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
- gEfiMtftp4ServiceBindingProtocolGuid ## CONSUMES
- gEfiMtftp4ProtocolGuid ## CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
- gEfiShellDynamicCommandProtocolGuid ## PRODUCES
-
-[DEPEX]
- TRUE
+## @file +# Provides Shell 'tftp' dynamic command. +# +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR> +# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = tftpDynamicCommand + FILE_GUID = A487A478-51EF-48AA-8794-7BEE2A0562F1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = TftpCommandInitialize + UNLOAD_IMAGE = TftpUnload +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + Tftp.uni + Tftp.h + Tftp.c + TftpDynamicCommand.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiHiiServicesLib + HiiLib + FileHandleLib + NetLib + +[Protocols] + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES + gEfiMtftp4ServiceBindingProtocolGuid ## CONSUMES + gEfiMtftp4ProtocolGuid ## CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + gEfiShellDynamicCommandProtocolGuid ## PRODUCES + +[DEPEX] + TRUE diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c index ed991be4ed..5a2d88c82a 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c @@ -1,897 +1,897 @@ -/** @file
- Main file for the "varpolicy" dynamic UEFI shell command and application.
-
- This feature can provide detailed UEFI variable policy configuration
- information in the UEFI shell.
-
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VariablePolicy.h"
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiHiiServicesLib.h>
-
-#include <Protocol/HiiPackageList.h>
-#include <Protocol/VariablePolicy.h>
-
-#define VAR_POLICY_FLAG_STATS_STR L"-s"
-#define VAR_POLICY_FLAG_POLICY_STR L"-p"
-#define VAR_POLICY_FLAG_VERBOSE_STR L"-v"
-
-#define VAR_POLICY_CMD_MIN_ATTR_STR_LEN 64
-
-EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle = NULL;
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { VAR_POLICY_FLAG_POLICY_STR, TypeFlag },
- { VAR_POLICY_FLAG_STATS_STR, TypeFlag },
- { VAR_POLICY_FLAG_VERBOSE_STR, TypeFlag },
- { NULL, TypeMax }
-};
-
-STATIC CONST VAR_POLICY_CMD_VAR_NAMESPACE mVarNamespaces[] = {
- {
- VariableVendorCapsule,
- &gEfiCapsuleVendorGuid,
- L"Capsule"
- },
- {
- VariableVendorCapsuleReport,
- &gEfiCapsuleReportGuid,
- L"Capsule Reporting"
- },
- {
- VariableVendorGlobal,
- &gEfiGlobalVariableGuid,
- L"UEFI Global"
- },
- {
- VariableVendorMemoryTypeInfo,
- &gEfiMemoryTypeInformationGuid,
- L"Memory Type Information"
- },
- {
- VariableVendorMonotonicCounter,
- &gMtcVendorGuid,
- L"Monotonic Counter"
- },
- {
- VariableVendorMorControl,
- &gEfiMemoryOverwriteRequestControlLockGuid,
- L"Memory Overwrite Request (MOR) Control Lock"
- },
- {
- VariableVendorShell,
- &gShellVariableGuid,
- L"UEFI Shell"
- },
- {
- VariableVendorShell,
- &gShellAliasGuid,
- L"UEFI Shell Alias"
- }
-};
-
-/**
- Returns UEFI variable attribute information in a string.
-
- AttributesStrSize must at least be VAR_POLICY_CMD_MIN_ATTR_STR_LEN in length
- or EFI_INVALID_PARAMETER will be returned.
-
- @param[in] Attributes The UEFI variable attributes.
- @param[in] AttributesStrSize The size, in bytes, of AttributesStr.
- @param[out] AttributesStr The Unicode string for the given attributes.
-
- @retval EFI_SUCCESS The attributes were converted to a string successfully.
- @retval EFI_INVALID_PARAMETER The AttributesStr pointer is NULL.
-
-**/
-EFI_STATUS
-GetAttributesString (
- IN UINT32 Attributes,
- IN UINTN AttributesStrSize,
- OUT CHAR16 *AttributesStr
- )
-{
- if ((AttributesStr == NULL) || (AttributesStrSize < VAR_POLICY_CMD_MIN_ATTR_STR_LEN)) {
- return EFI_INVALID_PARAMETER;
- }
-
- AttributesStr[0] = L'0';
- AttributesStr[1] = L'x';
- AttributesStr[2] = L'\0';
-
- UnicodeValueToStringS (AttributesStr + 2, AttributesStrSize - 2, (RADIX_HEX), (INT64)Attributes, 30);
-
- if (Attributes == 0) {
- StrCatS (AttributesStr, AttributesStrSize, L" No Attributes");
- } else {
- if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) {
- StrCatS (AttributesStr, AttributesStrSize, L" NV");
- Attributes ^= EFI_VARIABLE_NON_VOLATILE;
- }
-
- if ((Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) == EFI_VARIABLE_BOOTSERVICE_ACCESS) {
- StrCatS (AttributesStr, AttributesStrSize, L" BS");
- Attributes ^= EFI_VARIABLE_BOOTSERVICE_ACCESS;
- }
-
- if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == EFI_VARIABLE_RUNTIME_ACCESS) {
- StrCatS (AttributesStr, AttributesStrSize, L" RT");
- Attributes ^= EFI_VARIABLE_RUNTIME_ACCESS;
- }
-
- if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- StrCatS (AttributesStr, AttributesStrSize, L" HW-Error");
- Attributes ^= EFI_VARIABLE_HARDWARE_ERROR_RECORD;
- }
-
- if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
- StrCatS (AttributesStr, AttributesStrSize, L" Auth-WA");
- Attributes ^= EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
- }
-
- if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
- StrCatS (AttributesStr, AttributesStrSize, L" Auth-TIME-WA");
- Attributes ^= EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
- }
-
- if ((Attributes & EFI_VARIABLE_APPEND_WRITE) == EFI_VARIABLE_APPEND_WRITE) {
- StrCatS (AttributesStr, AttributesStrSize, L" APPEND-W");
- Attributes ^= EFI_VARIABLE_APPEND_WRITE;
- }
-
- if (Attributes != 0) {
- StrCatS (AttributesStr, AttributesStrSize, L" <Unknown Attribute>");
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Prints UEFI variable statistics information.
-
- @param[in] TotalVariables Total number of UEFI variables discovered.
- @param[in] TotalVariablesSize Total size of UEFI variables discovered.
-
-**/
-VOID
-PrintStats (
- IN UINTN TotalVariables,
- IN UINTN TotalVariablesSize
- )
-{
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_2), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_TOTAL_VARS), mVarPolicyShellCommandHiiHandle, TotalVariables);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_TOTAL_SIZE), mVarPolicyShellCommandHiiHandle, TotalVariablesSize, TotalVariablesSize);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
-}
-
-/**
- Returns information for the given variable namespace if available.
-
- @param[in] VariableGuid The UEFI variable vendor (namespace) GUID.
-
- @return Pointer to a namespace info structure on a GUID match.
- @return NULL on lack of a GUID match.
-
-**/
-CONST VAR_POLICY_CMD_VAR_NAMESPACE *
-GetNameSpaceInfo (
- IN EFI_GUID *VariableGuid
- )
-{
- UINTN Index;
-
- if (VariableGuid == NULL) {
- ASSERT (VariableGuid != NULL);
- return NULL;
- }
-
- for (Index = 0; Index < ARRAY_SIZE (mVarNamespaces); Index++) {
- if (CompareGuid (mVarNamespaces[Index].VendorGuid, VariableGuid)) {
- return &mVarNamespaces[Index];
- }
- }
-
- return NULL;
-}
-
-/**
- Print non-verbose information about the variable.
-
- @param[in] VariableName A pointer the Unicode variable name.
- @param[in] VariableGuid A pointer to the variable vendor GUID.
- @param[in] VariableSize The size of the UEFI variable in bytes.
- @param[in] VariableAttributes The UEFI variable attributes.
-
- @retval EFI_SUCCESS The non-verbose variable information was printed successfully.
- @retval EFI_INVALID_PARAMETER A pointer argument passed to the function was NULL.
- @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to print the attributes.
-
-**/
-EFI_STATUS
-PrintNonVerboseVarInfo (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VariableGuid,
- IN UINTN VariableSize,
- IN UINT32 VariableAttributes
- )
-{
- EFI_STATUS Status;
- CHAR16 *AttributesStr;
- CHAR16 *DescriptionStr;
- CONST VAR_POLICY_CMD_VAR_NAMESPACE *CmdVarNamespace;
-
- AttributesStr = NULL;
- DescriptionStr = NULL;
-
- if ((VariableName == NULL) || (VariableGuid == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- CmdVarNamespace = GetNameSpaceInfo (VariableGuid);
-
- if (CmdVarNamespace == NULL) {
- DescriptionStr = AllocatePages (1);
- if (DescriptionStr == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- ZeroMem ((VOID *)DescriptionStr, EFI_PAGES_TO_SIZE (1));
- UnicodeSPrint (DescriptionStr, EFI_PAGES_TO_SIZE (1), L"Unknown Vendor (%g)", VariableGuid);
- } else {
- DescriptionStr = CmdVarNamespace->Description;
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_TYPE), mVarPolicyShellCommandHiiHandle, DescriptionStr);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_NAME), mVarPolicyShellCommandHiiHandle, VariableName);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_SIZE), mVarPolicyShellCommandHiiHandle, VariableSize, VariableSize);
-
- AttributesStr = AllocatePages (1);
- if (AttributesStr == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- ZeroMem ((VOID *)AttributesStr, EFI_PAGES_TO_SIZE (1));
- Status = GetAttributesString (VariableAttributes, EFI_PAGES_TO_SIZE (1), AttributesStr);
- if (Status == EFI_SUCCESS) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_VAR_ATTR),
- mVarPolicyShellCommandHiiHandle,
- AttributesStr
- );
- }
-
- Status = EFI_SUCCESS;
-
-Exit:
- if (AttributesStr != NULL) {
- FreePages (AttributesStr, 1);
- }
-
- if ((CmdVarNamespace == NULL) && (DescriptionStr != NULL)) {
- FreePages (DescriptionStr, 1);
- }
-
- return Status;
-}
-
-/**
- Print verbose information about the variable.
-
- @param[in] Data A pointer to the variable data buffer.
- @param[in] DataSize The size of data, in bytes, in the variable data buffer.
-
- @retval EFI_SUCCESS The verbose variable information was printed successfully.
- @retval EFI_INVALID_PARAMETER A pointer argument passed to the function was NULL.
-
-**/
-EFI_STATUS
-PrintVerboseVarInfo (
- IN VOID *Data,
- IN UINTN DataSize
- )
-{
- if ((DataSize == 0) || (Data == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- VAR_POLICY_CMD_SHELL_DUMP_HEX (0, Data, DataSize);
-
- return EFI_SUCCESS;
-}
-
-/**
- Prints variable policy information for the given variable.
-
- @param[in] VariableName A pointer to the Unicode string of the UEFI variable name.
- @param[in] VendorGuid A pointer to the UEFI variable vendor GUID.
-
- @return TRUE if a variable policy was found and printed for the variable.
- @return FALSE if an error occurred and/or a variable policy was not found and
- printed for the variable.
-
-**/
-BOOLEAN
-PrintVariablePolicyInfo (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid
- )
-{
- EFI_STATUS Status;
- VARIABLE_POLICY_ENTRY VariablePolicyEntry;
- VARIABLE_LOCK_ON_VAR_STATE_POLICY LockOnVarStatePolicy;
- UINTN VariablePolicyVariableNameBufferSize;
- UINTN ReturnedVariableNameSize;
- BOOLEAN PolicyHeaderPresent;
- CHAR16 *VariablePolicyVariableName;
- CHAR16 *VariableAttributesStr;
- EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy;
-
- PolicyHeaderPresent = FALSE;
- VariableAttributesStr = NULL;
- VariablePolicyVariableName = NULL;
-
- if ((VariableName == NULL) || (VendorGuid == NULL)) {
- ASSERT ((VariableName != NULL) && (VendorGuid != NULL));
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_INT_ERR), mVarPolicyShellCommandHiiHandle);
- return FALSE;
- }
-
- Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NO_PROT), mVarPolicyShellCommandHiiHandle);
- return FALSE;
- }
-
- VariablePolicyVariableNameBufferSize = EFI_PAGES_TO_SIZE (1);
- VariablePolicyVariableName = AllocatePages (EFI_SIZE_TO_PAGES (VariablePolicyVariableNameBufferSize));
- if (VariablePolicyVariableName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- ASSERT_EFI_ERROR (Status);
- goto Done;
- }
-
- ZeroMem (VariablePolicyVariableName, VariablePolicyVariableNameBufferSize);
- ReturnedVariableNameSize = VariablePolicyVariableNameBufferSize;
- Status = VariablePolicy->GetVariablePolicyInfo (
- VariableName,
- VendorGuid,
- &ReturnedVariableNameSize,
- &VariablePolicyEntry,
- VariablePolicyVariableName
- );
- if (Status == EFI_NOT_READY) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NOT_INIT), mVarPolicyShellCommandHiiHandle);
- } else if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NOT_FOUND), mVarPolicyShellCommandHiiHandle);
- } else if (EFI_ERROR (Status)) {
- // A different error return code is not expected
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle, Status);
- } else {
- PolicyHeaderPresent = TRUE;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_2), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VERSION), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.Version);
-
- if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableName[0] != CHAR_NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableName);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle, L"<Entire Namespace>");
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NAMESPACE), mVarPolicyShellCommandHiiHandle, &VariablePolicyEntry.Namespace);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_MIN_SIZE), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.MinSize);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_MAX_SIZE), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.MaxSize);
-
- switch (VariablePolicyEntry.LockPolicyType) {
- case VARIABLE_POLICY_TYPE_NO_LOCK:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"No Lock");
- break;
- case VARIABLE_POLICY_TYPE_LOCK_NOW:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"Lock Now");
- break;
- case VARIABLE_POLICY_TYPE_LOCK_ON_CREATE:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"On Create");
- break;
- case VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"On Variable State");
-
- ZeroMem (VariablePolicyVariableName, VariablePolicyVariableNameBufferSize);
- ReturnedVariableNameSize = VariablePolicyVariableNameBufferSize;
- Status = VariablePolicy->GetLockOnVariableStateVariablePolicyInfo (
- VariableName,
- VendorGuid,
- &ReturnedVariableNameSize,
- &LockOnVarStatePolicy,
- VariablePolicyVariableName
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle, Status);
- goto Done;
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NS), mVarPolicyShellCommandHiiHandle, &LockOnVarStatePolicy.Namespace);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_VAL), mVarPolicyShellCommandHiiHandle, LockOnVarStatePolicy.Value);
- if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableName[0] != CHAR_NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableName);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, L"<Entire Namespace>");
- }
- }
-
- break;
- default:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"Unknown");
- break;
- }
-
- VariableAttributesStr = AllocatePages (1);
- if (VariableAttributesStr == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- ASSERT_EFI_ERROR (Status);
- goto Done;
- }
-
- ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1));
- Status = GetAttributesString (VariablePolicyEntry.AttributesMustHave, EFI_PAGES_TO_SIZE (1), VariableAttributesStr);
- if (Status == EFI_SUCCESS) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_MUST),
- mVarPolicyShellCommandHiiHandle
- );
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN),
- mVarPolicyShellCommandHiiHandle,
- VariableAttributesStr
- );
- }
-
- ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1));
- Status = GetAttributesString (VariablePolicyEntry.AttributesCantHave, EFI_PAGES_TO_SIZE (1), VariableAttributesStr);
- if (Status == EFI_SUCCESS) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_NOT),
- mVarPolicyShellCommandHiiHandle
- );
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN),
- mVarPolicyShellCommandHiiHandle,
- VariableAttributesStr
- );
- }
- }
-
-Done:
- if (PolicyHeaderPresent) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
- }
-
- if (VariableAttributesStr != NULL) {
- FreePages (VariableAttributesStr, 1);
- }
-
- if (VariablePolicyVariableName != NULL) {
- FreePages (VariablePolicyVariableName, 1);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
-
- return Status == EFI_SUCCESS;
-}
-
-/**
- Gets the next UEFI variable name.
-
- This buffer manages the UEFI variable name buffer, performing memory reallocations as necessary.
-
- Note: The first time this function is called, VariableNameBufferSize must be 0 and
- the VariableName buffer pointer must point to NULL.
-
- @param[in,out] VariableNameBufferSize On input, a pointer to a buffer that holds the current
- size of the VariableName buffer in bytes.
- On output, a pointer to a buffer that holds the updated
- size of the VariableName buffer in bytes.
- @param[in,out] VariableName On input, a pointer to a pointer to a buffer that holds the
- current UEFI variable name.
- On output, a pointer to a pointer to a buffer that holds the
- next UEFI variable name.
- @param[in,out] VariableGuid On input, a pointer to a buffer that holds the current UEFI
- variable GUID.
- On output, a pointer to a buffer that holds the next UEFI
- variable GUID.
-
- @retval EFI_SUCCESS The next UEFI variable name was found successfully.
- @retval EFI_INVALID_PARAMETER A pointer argument is NULL or initial input values are invalid.
- @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate a required buffer.
- @retval Others Return status codes from the UEFI spec define GetNextVariableName() interface.
-
-**/
-EFI_STATUS
-GetNextVariableNameWithDynamicReallocation (
- IN OUT UINTN *VariableNameBufferSize,
- IN OUT CHAR16 **VariableName,
- IN OUT EFI_GUID *VariableGuid
- )
-{
- EFI_STATUS Status;
- UINTN NextVariableNameBufferSize;
-
- if ((VariableNameBufferSize == NULL) || (VariableName == NULL) || (VariableGuid == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (*VariableNameBufferSize == 0) {
- if (*VariableName != NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Allocate a buffer to temporarily hold variable names. To reduce memory
- // allocations, the default buffer size is 256 characters. The buffer can
- // be reallocated if expansion is necessary (should be very rare).
- //
- *VariableNameBufferSize = sizeof (CHAR16) * 256;
- *VariableName = AllocateZeroPool (*VariableNameBufferSize);
- if (*VariableName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- ZeroMem ((VOID *)VariableGuid, sizeof (EFI_GUID));
- }
-
- NextVariableNameBufferSize = *VariableNameBufferSize;
- Status = gRT->GetNextVariableName (
- &NextVariableNameBufferSize,
- *VariableName,
- VariableGuid
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- *VariableName = ReallocatePool (
- *VariableNameBufferSize,
- NextVariableNameBufferSize,
- *VariableName
- );
- if (*VariableName == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- *VariableNameBufferSize = NextVariableNameBufferSize;
-
- Status = gRT->GetNextVariableName (
- &NextVariableNameBufferSize,
- *VariableName,
- VariableGuid
- );
- ASSERT (Status != EFI_BUFFER_TOO_SMALL);
- }
-
- return Status;
-}
-
-/**
- Dumps UEFI variable information.
-
- This is the main function that enumerates UEFI variables and prints the information
- selected by the user.
-
- @param[in] Verbose Whether to print verbose information.
- @param[in] Stats Whether to print statistical information.
- @param[in] PolicyCheck Whether to print variable policy related information.
-
-
- @retval EFI_SUCCESS The UEFI variable information was dumped successfully.
- @retval EFI_DEVICE_ERROR An error occurred attempting to get UEFI variable information.
- @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate a required buffer.
-
-**/
-EFI_STATUS
-DumpVars (
- IN BOOLEAN Verbose,
- IN BOOLEAN Stats,
- IN BOOLEAN PolicyCheck
- )
-{
- EFI_STATUS Status;
- EFI_STATUS GetNextVariableStatus;
- UINT32 Attributes;
- UINTN CurrentVariableDataBufferSize;
- UINTN DataSize;
- UINTN TotalDataSize;
- UINTN TotalVariables;
- UINTN TotalVariablesWithPolicy;
- UINTN VariableNameBufferSize;
- EFI_GUID VariableGuid;
- CHAR16 *VariableName;
- VOID *Data;
-
- Status = EFI_SUCCESS;
- Data = NULL;
- VariableName = NULL;
- CurrentVariableDataBufferSize = 0;
- TotalDataSize = 0;
- TotalVariables = 0;
- TotalVariablesWithPolicy = 0;
- VariableNameBufferSize = 0;
-
- do {
- GetNextVariableStatus = GetNextVariableNameWithDynamicReallocation (
- &VariableNameBufferSize,
- &VariableName,
- &VariableGuid
- );
-
- if (!EFI_ERROR (GetNextVariableStatus)) {
- DataSize = 0;
- Status = gRT->GetVariable (
- VariableName,
- &VariableGuid,
- &Attributes,
- &DataSize,
- NULL
- );
- if (Status != EFI_BUFFER_TOO_SMALL) {
- // If the variable exists, a zero size buffer should be too small
- Status = EFI_DEVICE_ERROR;
- goto DeallocateAndExit;
- }
-
- TotalDataSize += DataSize;
- TotalVariables++;
-
- if (!Stats || Verbose) {
- Status = PrintNonVerboseVarInfo (VariableName, &VariableGuid, DataSize, Attributes);
- if (!EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
- }
- }
-
- if (PolicyCheck || Verbose) {
- if (PrintVariablePolicyInfo (VariableName, &VariableGuid)) {
- TotalVariablesWithPolicy++;
- }
- }
-
- if (Verbose) {
- if (CurrentVariableDataBufferSize < DataSize) {
- if (Data != NULL) {
- FreePool (Data);
- }
-
- Data = AllocateZeroPool (DataSize);
- if (Data == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto DeallocateAndExit;
- }
-
- CurrentVariableDataBufferSize = DataSize;
- }
-
- Status = gRT->GetVariable (
- VariableName,
- &VariableGuid,
- NULL,
- &DataSize,
- Data
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto DeallocateAndExit;
- }
-
- Status = PrintVerboseVarInfo (Data, DataSize);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto DeallocateAndExit;
- }
- }
- }
- } while (!EFI_ERROR (GetNextVariableStatus));
-
- if (TotalVariables == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VARS), mVarPolicyShellCommandHiiHandle);
- } else {
- if (Verbose || Stats) {
- PrintStats (TotalVariables, TotalDataSize);
- }
-
- if (Verbose || PolicyCheck) {
- ASSERT (TotalVariablesWithPolicy <= TotalVariables);
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
- if (TotalVariablesWithPolicy == TotalVariables) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_STATS_PASS),
- mVarPolicyShellCommandHiiHandle,
- TotalVariablesWithPolicy,
- TotalVariables
- );
- } else {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_VAR_POL_POLICY_STATS_FAIL),
- mVarPolicyShellCommandHiiHandle,
- TotalVariablesWithPolicy,
- TotalVariables
- );
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
- }
- }
-
- Status = EFI_SUCCESS;
-
-DeallocateAndExit:
- if (VariableName != NULL) {
- FreePool (VariableName);
- }
-
- if (Data != NULL) {
- FreePool (Data);
- }
-
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
-
-/**
- Main entry function for the "varpolicy" command/app.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The "varpolicy" shell command executed successfully.
- @retval SHELL_ABORTED Failed to initialize the shell library.
- @retval SHELL_INVALID_PARAMETER An argument passed to the shell command is invalid.
- @retval Others A different error occurred.
-
-**/
-SHELL_STATUS
-EFIAPI
-RunVarPolicy (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- BOOLEAN PolicyCheck;
- BOOLEAN StatsDump;
- BOOLEAN VerboseDump;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
-
- Package = NULL;
- ShellStatus = SHELL_INVALID_PARAMETER;
- Status = EFI_SUCCESS;
- PolicyCheck = FALSE;
- StatsDump = FALSE;
- VerboseDump = FALSE;
-
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
-
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), mVarPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME, ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto Done;
- } else {
- ASSERT (FALSE);
- }
- } else {
- if (ShellCommandLineGetCount (Package) > 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), mVarPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto Done;
- }
-
- PolicyCheck = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_POLICY_STR);
- StatsDump = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_STATS_STR);
- VerboseDump = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_VERBOSE_STR);
-
- Status = DumpVars (VerboseDump, StatsDump, PolicyCheck);
- ASSERT_EFI_ERROR (Status);
- }
-
-Done:
- if (Package != NULL) {
- ShellCommandLineFreeVarList (Package);
- }
-
- return ShellStatus;
-}
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param[in] ImageHandle The image handle of the process.
-
- @return HII handle.
-
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Retrieve HII package list from ImageHandle
- //
- Status = gBS->OpenProtocol (
- ImageHandle,
- &gEfiHiiPackageListProtocolGuid,
- (VOID **)&PackageList,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Publish HII package list to HII Database.
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageList,
- NULL,
- &HiiHandle
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return HiiHandle;
-}
+/** @file + Main file for the "varpolicy" dynamic UEFI shell command and application. + + This feature can provide detailed UEFI variable policy configuration + information in the UEFI shell. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VariablePolicy.h" + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/HiiLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PrintLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiHiiServicesLib.h> + +#include <Protocol/HiiPackageList.h> +#include <Protocol/VariablePolicy.h> + +#define VAR_POLICY_FLAG_STATS_STR L"-s" +#define VAR_POLICY_FLAG_POLICY_STR L"-p" +#define VAR_POLICY_FLAG_VERBOSE_STR L"-v" + +#define VAR_POLICY_CMD_MIN_ATTR_STR_LEN 64 + +EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle = NULL; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { VAR_POLICY_FLAG_POLICY_STR, TypeFlag }, + { VAR_POLICY_FLAG_STATS_STR, TypeFlag }, + { VAR_POLICY_FLAG_VERBOSE_STR, TypeFlag }, + { NULL, TypeMax } +}; + +STATIC CONST VAR_POLICY_CMD_VAR_NAMESPACE mVarNamespaces[] = { + { + VariableVendorCapsule, + &gEfiCapsuleVendorGuid, + L"Capsule" + }, + { + VariableVendorCapsuleReport, + &gEfiCapsuleReportGuid, + L"Capsule Reporting" + }, + { + VariableVendorGlobal, + &gEfiGlobalVariableGuid, + L"UEFI Global" + }, + { + VariableVendorMemoryTypeInfo, + &gEfiMemoryTypeInformationGuid, + L"Memory Type Information" + }, + { + VariableVendorMonotonicCounter, + &gMtcVendorGuid, + L"Monotonic Counter" + }, + { + VariableVendorMorControl, + &gEfiMemoryOverwriteRequestControlLockGuid, + L"Memory Overwrite Request (MOR) Control Lock" + }, + { + VariableVendorShell, + &gShellVariableGuid, + L"UEFI Shell" + }, + { + VariableVendorShell, + &gShellAliasGuid, + L"UEFI Shell Alias" + } +}; + +/** + Returns UEFI variable attribute information in a string. + + AttributesStrSize must at least be VAR_POLICY_CMD_MIN_ATTR_STR_LEN in length + or EFI_INVALID_PARAMETER will be returned. + + @param[in] Attributes The UEFI variable attributes. + @param[in] AttributesStrSize The size, in bytes, of AttributesStr. + @param[out] AttributesStr The Unicode string for the given attributes. + + @retval EFI_SUCCESS The attributes were converted to a string successfully. + @retval EFI_INVALID_PARAMETER The AttributesStr pointer is NULL. + +**/ +EFI_STATUS +GetAttributesString ( + IN UINT32 Attributes, + IN UINTN AttributesStrSize, + OUT CHAR16 *AttributesStr + ) +{ + if ((AttributesStr == NULL) || (AttributesStrSize < VAR_POLICY_CMD_MIN_ATTR_STR_LEN)) { + return EFI_INVALID_PARAMETER; + } + + AttributesStr[0] = L'0'; + AttributesStr[1] = L'x'; + AttributesStr[2] = L'\0'; + + UnicodeValueToStringS (AttributesStr + 2, AttributesStrSize - 2, (RADIX_HEX), (INT64)Attributes, 30); + + if (Attributes == 0) { + StrCatS (AttributesStr, AttributesStrSize, L" No Attributes"); + } else { + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE) { + StrCatS (AttributesStr, AttributesStrSize, L" NV"); + Attributes ^= EFI_VARIABLE_NON_VOLATILE; + } + + if ((Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) == EFI_VARIABLE_BOOTSERVICE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" BS"); + Attributes ^= EFI_VARIABLE_BOOTSERVICE_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == EFI_VARIABLE_RUNTIME_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" RT"); + Attributes ^= EFI_VARIABLE_RUNTIME_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + StrCatS (AttributesStr, AttributesStrSize, L" HW-Error"); + Attributes ^= EFI_VARIABLE_HARDWARE_ERROR_RECORD; + } + + if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" Auth-WA"); + Attributes ^= EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" Auth-TIME-WA"); + Attributes ^= EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_APPEND_WRITE) == EFI_VARIABLE_APPEND_WRITE) { + StrCatS (AttributesStr, AttributesStrSize, L" APPEND-W"); + Attributes ^= EFI_VARIABLE_APPEND_WRITE; + } + + if (Attributes != 0) { + StrCatS (AttributesStr, AttributesStrSize, L" <Unknown Attribute>"); + } + } + + return EFI_SUCCESS; +} + +/** + Prints UEFI variable statistics information. + + @param[in] TotalVariables Total number of UEFI variables discovered. + @param[in] TotalVariablesSize Total size of UEFI variables discovered. + +**/ +VOID +PrintStats ( + IN UINTN TotalVariables, + IN UINTN TotalVariablesSize + ) +{ + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_2), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_TOTAL_VARS), mVarPolicyShellCommandHiiHandle, TotalVariables); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_TOTAL_SIZE), mVarPolicyShellCommandHiiHandle, TotalVariablesSize, TotalVariablesSize); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle); +} + +/** + Returns information for the given variable namespace if available. + + @param[in] VariableGuid The UEFI variable vendor (namespace) GUID. + + @return Pointer to a namespace info structure on a GUID match. + @return NULL on lack of a GUID match. + +**/ +CONST VAR_POLICY_CMD_VAR_NAMESPACE * +GetNameSpaceInfo ( + IN EFI_GUID *VariableGuid + ) +{ + UINTN Index; + + if (VariableGuid == NULL) { + ASSERT (VariableGuid != NULL); + return NULL; + } + + for (Index = 0; Index < ARRAY_SIZE (mVarNamespaces); Index++) { + if (CompareGuid (mVarNamespaces[Index].VendorGuid, VariableGuid)) { + return &mVarNamespaces[Index]; + } + } + + return NULL; +} + +/** + Print non-verbose information about the variable. + + @param[in] VariableName A pointer the Unicode variable name. + @param[in] VariableGuid A pointer to the variable vendor GUID. + @param[in] VariableSize The size of the UEFI variable in bytes. + @param[in] VariableAttributes The UEFI variable attributes. + + @retval EFI_SUCCESS The non-verbose variable information was printed successfully. + @retval EFI_INVALID_PARAMETER A pointer argument passed to the function was NULL. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to print the attributes. + +**/ +EFI_STATUS +PrintNonVerboseVarInfo ( + IN CHAR16 *VariableName, + IN EFI_GUID *VariableGuid, + IN UINTN VariableSize, + IN UINT32 VariableAttributes + ) +{ + EFI_STATUS Status; + CHAR16 *AttributesStr; + CHAR16 *DescriptionStr; + CONST VAR_POLICY_CMD_VAR_NAMESPACE *CmdVarNamespace; + + AttributesStr = NULL; + DescriptionStr = NULL; + + if ((VariableName == NULL) || (VariableGuid == NULL)) { + return EFI_INVALID_PARAMETER; + } + + CmdVarNamespace = GetNameSpaceInfo (VariableGuid); + + if (CmdVarNamespace == NULL) { + DescriptionStr = AllocatePages (1); + if (DescriptionStr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + ZeroMem ((VOID *)DescriptionStr, EFI_PAGES_TO_SIZE (1)); + UnicodeSPrint (DescriptionStr, EFI_PAGES_TO_SIZE (1), L"Unknown Vendor (%g)", VariableGuid); + } else { + DescriptionStr = CmdVarNamespace->Description; + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_TYPE), mVarPolicyShellCommandHiiHandle, DescriptionStr); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_NAME), mVarPolicyShellCommandHiiHandle, VariableName); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_SIZE), mVarPolicyShellCommandHiiHandle, VariableSize, VariableSize); + + AttributesStr = AllocatePages (1); + if (AttributesStr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + ZeroMem ((VOID *)AttributesStr, EFI_PAGES_TO_SIZE (1)); + Status = GetAttributesString (VariableAttributes, EFI_PAGES_TO_SIZE (1), AttributesStr); + if (Status == EFI_SUCCESS) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_VAR_ATTR), + mVarPolicyShellCommandHiiHandle, + AttributesStr + ); + } + + Status = EFI_SUCCESS; + +Exit: + if (AttributesStr != NULL) { + FreePages (AttributesStr, 1); + } + + if ((CmdVarNamespace == NULL) && (DescriptionStr != NULL)) { + FreePages (DescriptionStr, 1); + } + + return Status; +} + +/** + Print verbose information about the variable. + + @param[in] Data A pointer to the variable data buffer. + @param[in] DataSize The size of data, in bytes, in the variable data buffer. + + @retval EFI_SUCCESS The verbose variable information was printed successfully. + @retval EFI_INVALID_PARAMETER A pointer argument passed to the function was NULL. + +**/ +EFI_STATUS +PrintVerboseVarInfo ( + IN VOID *Data, + IN UINTN DataSize + ) +{ + if ((DataSize == 0) || (Data == NULL)) { + return EFI_INVALID_PARAMETER; + } + + VAR_POLICY_CMD_SHELL_DUMP_HEX (0, Data, DataSize); + + return EFI_SUCCESS; +} + +/** + Prints variable policy information for the given variable. + + @param[in] VariableName A pointer to the Unicode string of the UEFI variable name. + @param[in] VendorGuid A pointer to the UEFI variable vendor GUID. + + @return TRUE if a variable policy was found and printed for the variable. + @return FALSE if an error occurred and/or a variable policy was not found and + printed for the variable. + +**/ +BOOLEAN +PrintVariablePolicyInfo ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY VariablePolicyEntry; + VARIABLE_LOCK_ON_VAR_STATE_POLICY LockOnVarStatePolicy; + UINTN VariablePolicyVariableNameBufferSize; + UINTN ReturnedVariableNameSize; + BOOLEAN PolicyHeaderPresent; + CHAR16 *VariablePolicyVariableName; + CHAR16 *VariableAttributesStr; + EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy; + + PolicyHeaderPresent = FALSE; + VariableAttributesStr = NULL; + VariablePolicyVariableName = NULL; + + if ((VariableName == NULL) || (VendorGuid == NULL)) { + ASSERT ((VariableName != NULL) && (VendorGuid != NULL)); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_INT_ERR), mVarPolicyShellCommandHiiHandle); + return FALSE; + } + + Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NO_PROT), mVarPolicyShellCommandHiiHandle); + return FALSE; + } + + VariablePolicyVariableNameBufferSize = EFI_PAGES_TO_SIZE (1); + VariablePolicyVariableName = AllocatePages (EFI_SIZE_TO_PAGES (VariablePolicyVariableNameBufferSize)); + if (VariablePolicyVariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto Done; + } + + ZeroMem (VariablePolicyVariableName, VariablePolicyVariableNameBufferSize); + ReturnedVariableNameSize = VariablePolicyVariableNameBufferSize; + Status = VariablePolicy->GetVariablePolicyInfo ( + VariableName, + VendorGuid, + &ReturnedVariableNameSize, + &VariablePolicyEntry, + VariablePolicyVariableName + ); + if (Status == EFI_NOT_READY) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NOT_INIT), mVarPolicyShellCommandHiiHandle); + } else if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NOT_FOUND), mVarPolicyShellCommandHiiHandle); + } else if (EFI_ERROR (Status)) { + // A different error return code is not expected + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle, Status); + } else { + PolicyHeaderPresent = TRUE; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_2), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VERSION), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.Version); + + if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableName[0] != CHAR_NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle, L"<Entire Namespace>"); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NAMESPACE), mVarPolicyShellCommandHiiHandle, &VariablePolicyEntry.Namespace); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_MIN_SIZE), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.MinSize); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_MAX_SIZE), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.MaxSize); + + switch (VariablePolicyEntry.LockPolicyType) { + case VARIABLE_POLICY_TYPE_NO_LOCK: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"No Lock"); + break; + case VARIABLE_POLICY_TYPE_LOCK_NOW: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"Lock Now"); + break; + case VARIABLE_POLICY_TYPE_LOCK_ON_CREATE: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"On Create"); + break; + case VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"On Variable State"); + + ZeroMem (VariablePolicyVariableName, VariablePolicyVariableNameBufferSize); + ReturnedVariableNameSize = VariablePolicyVariableNameBufferSize; + Status = VariablePolicy->GetLockOnVariableStateVariablePolicyInfo ( + VariableName, + VendorGuid, + &ReturnedVariableNameSize, + &LockOnVarStatePolicy, + VariablePolicyVariableName + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle, Status); + goto Done; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NS), mVarPolicyShellCommandHiiHandle, &LockOnVarStatePolicy.Namespace); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_VAL), mVarPolicyShellCommandHiiHandle, LockOnVarStatePolicy.Value); + if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableName[0] != CHAR_NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, L"<Entire Namespace>"); + } + } + + break; + default: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"Unknown"); + break; + } + + VariableAttributesStr = AllocatePages (1); + if (VariableAttributesStr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto Done; + } + + ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1)); + Status = GetAttributesString (VariablePolicyEntry.AttributesMustHave, EFI_PAGES_TO_SIZE (1), VariableAttributesStr); + if (Status == EFI_SUCCESS) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_MUST), + mVarPolicyShellCommandHiiHandle + ); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN), + mVarPolicyShellCommandHiiHandle, + VariableAttributesStr + ); + } + + ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1)); + Status = GetAttributesString (VariablePolicyEntry.AttributesCantHave, EFI_PAGES_TO_SIZE (1), VariableAttributesStr); + if (Status == EFI_SUCCESS) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_NOT), + mVarPolicyShellCommandHiiHandle + ); + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN), + mVarPolicyShellCommandHiiHandle, + VariableAttributesStr + ); + } + } + +Done: + if (PolicyHeaderPresent) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle); + } + + if (VariableAttributesStr != NULL) { + FreePages (VariableAttributesStr, 1); + } + + if (VariablePolicyVariableName != NULL) { + FreePages (VariablePolicyVariableName, 1); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); + + return Status == EFI_SUCCESS; +} + +/** + Gets the next UEFI variable name. + + This buffer manages the UEFI variable name buffer, performing memory reallocations as necessary. + + Note: The first time this function is called, VariableNameBufferSize must be 0 and + the VariableName buffer pointer must point to NULL. + + @param[in,out] VariableNameBufferSize On input, a pointer to a buffer that holds the current + size of the VariableName buffer in bytes. + On output, a pointer to a buffer that holds the updated + size of the VariableName buffer in bytes. + @param[in,out] VariableName On input, a pointer to a pointer to a buffer that holds the + current UEFI variable name. + On output, a pointer to a pointer to a buffer that holds the + next UEFI variable name. + @param[in,out] VariableGuid On input, a pointer to a buffer that holds the current UEFI + variable GUID. + On output, a pointer to a buffer that holds the next UEFI + variable GUID. + + @retval EFI_SUCCESS The next UEFI variable name was found successfully. + @retval EFI_INVALID_PARAMETER A pointer argument is NULL or initial input values are invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate a required buffer. + @retval Others Return status codes from the UEFI spec define GetNextVariableName() interface. + +**/ +EFI_STATUS +GetNextVariableNameWithDynamicReallocation ( + IN OUT UINTN *VariableNameBufferSize, + IN OUT CHAR16 **VariableName, + IN OUT EFI_GUID *VariableGuid + ) +{ + EFI_STATUS Status; + UINTN NextVariableNameBufferSize; + + if ((VariableNameBufferSize == NULL) || (VariableName == NULL) || (VariableGuid == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (*VariableNameBufferSize == 0) { + if (*VariableName != NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Allocate a buffer to temporarily hold variable names. To reduce memory + // allocations, the default buffer size is 256 characters. The buffer can + // be reallocated if expansion is necessary (should be very rare). + // + *VariableNameBufferSize = sizeof (CHAR16) * 256; + *VariableName = AllocateZeroPool (*VariableNameBufferSize); + if (*VariableName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *)VariableGuid, sizeof (EFI_GUID)); + } + + NextVariableNameBufferSize = *VariableNameBufferSize; + Status = gRT->GetNextVariableName ( + &NextVariableNameBufferSize, + *VariableName, + VariableGuid + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + *VariableName = ReallocatePool ( + *VariableNameBufferSize, + NextVariableNameBufferSize, + *VariableName + ); + if (*VariableName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *VariableNameBufferSize = NextVariableNameBufferSize; + + Status = gRT->GetNextVariableName ( + &NextVariableNameBufferSize, + *VariableName, + VariableGuid + ); + ASSERT (Status != EFI_BUFFER_TOO_SMALL); + } + + return Status; +} + +/** + Dumps UEFI variable information. + + This is the main function that enumerates UEFI variables and prints the information + selected by the user. + + @param[in] Verbose Whether to print verbose information. + @param[in] Stats Whether to print statistical information. + @param[in] PolicyCheck Whether to print variable policy related information. + + + @retval EFI_SUCCESS The UEFI variable information was dumped successfully. + @retval EFI_DEVICE_ERROR An error occurred attempting to get UEFI variable information. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate a required buffer. + +**/ +EFI_STATUS +DumpVars ( + IN BOOLEAN Verbose, + IN BOOLEAN Stats, + IN BOOLEAN PolicyCheck + ) +{ + EFI_STATUS Status; + EFI_STATUS GetNextVariableStatus; + UINT32 Attributes; + UINTN CurrentVariableDataBufferSize; + UINTN DataSize; + UINTN TotalDataSize; + UINTN TotalVariables; + UINTN TotalVariablesWithPolicy; + UINTN VariableNameBufferSize; + EFI_GUID VariableGuid; + CHAR16 *VariableName; + VOID *Data; + + Status = EFI_SUCCESS; + Data = NULL; + VariableName = NULL; + CurrentVariableDataBufferSize = 0; + TotalDataSize = 0; + TotalVariables = 0; + TotalVariablesWithPolicy = 0; + VariableNameBufferSize = 0; + + do { + GetNextVariableStatus = GetNextVariableNameWithDynamicReallocation ( + &VariableNameBufferSize, + &VariableName, + &VariableGuid + ); + + if (!EFI_ERROR (GetNextVariableStatus)) { + DataSize = 0; + Status = gRT->GetVariable ( + VariableName, + &VariableGuid, + &Attributes, + &DataSize, + NULL + ); + if (Status != EFI_BUFFER_TOO_SMALL) { + // If the variable exists, a zero size buffer should be too small + Status = EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + + TotalDataSize += DataSize; + TotalVariables++; + + if (!Stats || Verbose) { + Status = PrintNonVerboseVarInfo (VariableName, &VariableGuid, DataSize, Attributes); + if (!EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); + } + } + + if (PolicyCheck || Verbose) { + if (PrintVariablePolicyInfo (VariableName, &VariableGuid)) { + TotalVariablesWithPolicy++; + } + } + + if (Verbose) { + if (CurrentVariableDataBufferSize < DataSize) { + if (Data != NULL) { + FreePool (Data); + } + + Data = AllocateZeroPool (DataSize); + if (Data == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto DeallocateAndExit; + } + + CurrentVariableDataBufferSize = DataSize; + } + + Status = gRT->GetVariable ( + VariableName, + &VariableGuid, + NULL, + &DataSize, + Data + ); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + + Status = PrintVerboseVarInfo (Data, DataSize); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + } + } + } while (!EFI_ERROR (GetNextVariableStatus)); + + if (TotalVariables == 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VARS), mVarPolicyShellCommandHiiHandle); + } else { + if (Verbose || Stats) { + PrintStats (TotalVariables, TotalDataSize); + } + + if (Verbose || PolicyCheck) { + ASSERT (TotalVariablesWithPolicy <= TotalVariables); + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); + if (TotalVariablesWithPolicy == TotalVariables) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_STATS_PASS), + mVarPolicyShellCommandHiiHandle, + TotalVariablesWithPolicy, + TotalVariables + ); + } else { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_POLICY_STATS_FAIL), + mVarPolicyShellCommandHiiHandle, + TotalVariablesWithPolicy, + TotalVariables + ); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); + } + } + + Status = EFI_SUCCESS; + +DeallocateAndExit: + if (VariableName != NULL) { + FreePool (VariableName); + } + + if (Data != NULL) { + FreePool (Data); + } + + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Main entry function for the "varpolicy" command/app. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). + + @retval SHELL_SUCCESS The "varpolicy" shell command executed successfully. + @retval SHELL_ABORTED Failed to initialize the shell library. + @retval SHELL_INVALID_PARAMETER An argument passed to the shell command is invalid. + @retval Others A different error occurred. + +**/ +SHELL_STATUS +EFIAPI +RunVarPolicy ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + BOOLEAN PolicyCheck; + BOOLEAN StatsDump; + BOOLEAN VerboseDump; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + + Package = NULL; + ShellStatus = SHELL_INVALID_PARAMETER; + Status = EFI_SUCCESS; + PolicyCheck = FALSE; + StatsDump = FALSE; + VerboseDump = FALSE; + + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), mVarPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME, ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } else { + ASSERT (FALSE); + } + } else { + if (ShellCommandLineGetCount (Package) > 1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), mVarPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + PolicyCheck = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_POLICY_STR); + StatsDump = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_STATS_STR); + VerboseDump = ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_VERBOSE_STR); + + Status = DumpVars (VerboseDump, StatsDump, PolicyCheck); + ASSERT_EFI_ERROR (Status); + } + +Done: + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + + return ShellStatus; +} + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param[in] ImageHandle The image handle of the process. + + @return HII handle. + +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + EFI_HII_HANDLE HiiHandle; + + // + // Retrieve HII package list from ImageHandle + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **)&PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + // + // Publish HII package list to HII Database. + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &HiiHandle + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + return HiiHandle; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.h b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.h index 0498232426..e640ab5db3 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.h +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.h @@ -1,129 +1,129 @@ -/** @file
- Internal header file for the module.
-
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_
-#define VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_
-
-#include <Uefi.h>
-#include <Protocol/Shell.h>
-
-#define VAR_POLICY_COMMAND_NAME L"varpolicy"
-
-typedef enum {
- VariableVendorCapsule,
- VariableVendorCapsuleReport,
- VariableVendorGlobal,
- VariableVendorMemoryTypeInfo,
- VariableVendorMonotonicCounter,
- VariableVendorMorControl,
- VariableVendorShell,
- VariableVendorGuidMax
-} VAR_POLICY_CMD_VENDOR_GUID_TYPE;
-
-typedef struct {
- VAR_POLICY_CMD_VENDOR_GUID_TYPE VendorGuidType;
- EFI_GUID *VendorGuid;
- CHAR16 *Description;
-} VAR_POLICY_CMD_VAR_NAMESPACE;
-
-/**
- Log a formatted console message.
-
- This is not specific to this shell command but scoped so to prevent global
- name conflicts.
-
- The hex dump is split into lines of 16 dumped bytes.
-
- The full hex dump is bracketed, and its byte ascii char also print.
- If the byte value is not an ascii code, it will print as '.'
-
- @param[in] Offset Offset to be display after PrefixFormat.
- Offset will be increased for each print line.
- @param[in] Data The data to dump.
- @param[in] DataSize Number of bytes in Data.
-
-**/
-#define VAR_POLICY_CMD_SHELL_DUMP_HEX(Offset, \
- Data, \
- DataSize \
- ) \
- { \
- UINT8 *_DataToDump; \
- UINT8 _Val[50]; \
- UINT8 _Str[20]; \
- UINT8 _TempByte; \
- UINTN _Size; \
- UINTN _DumpHexIndex; \
- UINTN _LocalOffset; \
- UINTN _LocalDataSize; \
- CONST CHAR8 *_Hex = "0123456789ABCDEF"; \
- _LocalOffset = (Offset); \
- _LocalDataSize = (DataSize); \
- _DataToDump = (UINT8 *)(Data); \
- \
- ASSERT (_DataToDump != NULL); \
- \
- while (_LocalDataSize != 0) { \
- _Size = 16; \
- if (_Size > _LocalDataSize) { \
- _Size = _LocalDataSize; \
- } \
- \
- for (_DumpHexIndex = 0; _DumpHexIndex < _Size; _DumpHexIndex += 1) { \
- _TempByte = (UINT8) _DataToDump[_DumpHexIndex]; \
- _Val[_DumpHexIndex * 3 + 0] = (UINT8) _Hex[_TempByte >> 4]; \
- _Val[_DumpHexIndex * 3 + 1] = (UINT8) _Hex[_TempByte & 0xF]; \
- _Val[_DumpHexIndex * 3 + 2] = \
- (CHAR8) ((_DumpHexIndex == 7) ? '-' : ' '); \
- _Str[_DumpHexIndex] = \
- (CHAR8) ((_TempByte < ' ' || _TempByte > '~') ? '.' : _TempByte); \
- } \
- \
- _Val[_DumpHexIndex * 3] = 0; \
- _Str[_DumpHexIndex] = 0; \
- \
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_HEX_DUMP_LINE), mVarPolicyShellCommandHiiHandle, _LocalOffset, _Val, _Str); \
- _DataToDump = (UINT8 *)(((UINTN)_DataToDump) + _Size); \
- _LocalOffset += _Size; \
- _LocalDataSize -= _Size; \
- } \
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); \
- }
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param[in] ImageHandle The image handle of the process.
-
- @return HII handle.
-
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- IN EFI_HANDLE ImageHandle
- );
-
-/**
- Main entry function for the "varpolicy" command/app.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The "varpolicy" shell command executed successfully.
- @retval SHELL_INVALID_PARAMETER An argument passed to the shell command is invalid.
- @retval Others A different error occurred.
-
-**/
-SHELL_STATUS
-EFIAPI
-RunVarPolicy (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-#endif
+/** @file + Internal header file for the module. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_ +#define VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_ + +#include <Uefi.h> +#include <Protocol/Shell.h> + +#define VAR_POLICY_COMMAND_NAME L"varpolicy" + +typedef enum { + VariableVendorCapsule, + VariableVendorCapsuleReport, + VariableVendorGlobal, + VariableVendorMemoryTypeInfo, + VariableVendorMonotonicCounter, + VariableVendorMorControl, + VariableVendorShell, + VariableVendorGuidMax +} VAR_POLICY_CMD_VENDOR_GUID_TYPE; + +typedef struct { + VAR_POLICY_CMD_VENDOR_GUID_TYPE VendorGuidType; + EFI_GUID *VendorGuid; + CHAR16 *Description; +} VAR_POLICY_CMD_VAR_NAMESPACE; + +/** + Log a formatted console message. + + This is not specific to this shell command but scoped so to prevent global + name conflicts. + + The hex dump is split into lines of 16 dumped bytes. + + The full hex dump is bracketed, and its byte ascii char also print. + If the byte value is not an ascii code, it will print as '.' + + @param[in] Offset Offset to be display after PrefixFormat. + Offset will be increased for each print line. + @param[in] Data The data to dump. + @param[in] DataSize Number of bytes in Data. + +**/ +#define VAR_POLICY_CMD_SHELL_DUMP_HEX(Offset, \ + Data, \ + DataSize \ + ) \ + { \ + UINT8 *_DataToDump; \ + UINT8 _Val[50]; \ + UINT8 _Str[20]; \ + UINT8 _TempByte; \ + UINTN _Size; \ + UINTN _DumpHexIndex; \ + UINTN _LocalOffset; \ + UINTN _LocalDataSize; \ + CONST CHAR8 *_Hex = "0123456789ABCDEF"; \ + _LocalOffset = (Offset); \ + _LocalDataSize = (DataSize); \ + _DataToDump = (UINT8 *)(Data); \ + \ + ASSERT (_DataToDump != NULL); \ + \ + while (_LocalDataSize != 0) { \ + _Size = 16; \ + if (_Size > _LocalDataSize) { \ + _Size = _LocalDataSize; \ + } \ + \ + for (_DumpHexIndex = 0; _DumpHexIndex < _Size; _DumpHexIndex += 1) { \ + _TempByte = (UINT8) _DataToDump[_DumpHexIndex]; \ + _Val[_DumpHexIndex * 3 + 0] = (UINT8) _Hex[_TempByte >> 4]; \ + _Val[_DumpHexIndex * 3 + 1] = (UINT8) _Hex[_TempByte & 0xF]; \ + _Val[_DumpHexIndex * 3 + 2] = \ + (CHAR8) ((_DumpHexIndex == 7) ? '-' : ' '); \ + _Str[_DumpHexIndex] = \ + (CHAR8) ((_TempByte < ' ' || _TempByte > '~') ? '.' : _TempByte); \ + } \ + \ + _Val[_DumpHexIndex * 3] = 0; \ + _Str[_DumpHexIndex] = 0; \ + \ + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_HEX_DUMP_LINE), mVarPolicyShellCommandHiiHandle, _LocalOffset, _Val, _Str); \ + _DataToDump = (UINT8 *)(((UINTN)_DataToDump) + _Size); \ + _LocalOffset += _Size; \ + _LocalDataSize -= _Size; \ + } \ + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); \ + } + +/** + Retrieve HII package list from ImageHandle and publish to HII database. + + @param[in] ImageHandle The image handle of the process. + + @return HII handle. + +**/ +EFI_HII_HANDLE +InitializeHiiPackage ( + IN EFI_HANDLE ImageHandle + ); + +/** + Main entry function for the "varpolicy" command/app. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). + + @retval SHELL_SUCCESS The "varpolicy" shell command executed successfully. + @retval SHELL_INVALID_PARAMETER An argument passed to the shell command is invalid. + @retval Others A different error occurred. + +**/ +SHELL_STATUS +EFIAPI +RunVarPolicy ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.uni b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.uni index 1944682856..5472ac6201 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.uni +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.uni @@ -1,86 +1,86 @@ -// /**
-// String definitions for the Variable Policy ("varpolicy") shell command/app.
-//
-// Copyright (c) Microsoft Corporation.
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-// General Strings
-#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
-#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n"
-#string STR_GEN_NO_VARS #language en-US "No UEFI variables found!\r\n"
-#string STR_GEN_LINE_BREAK #language en-US "\r\n"
-
-#string STR_GEN_HEX_DUMP_LINE #language en-US "%B%08X%N: %-48a %V*%a*%N\r\n"
-
-#string STR_VAR_POL_POLICY_INT_ERR #language en-US "%EInternal Application Error Getting Policy Info!%N\r\n"
-#string STR_VAR_POL_POLICY_NO_PROT #language en-US "%EVariable Policy Protocol Was Not Found!%N\r\n"
-#string STR_VAR_POL_POLICY_NOT_INIT #language en-US "%EUEFI Variable Policy is Not Initialized!%N\r\n"
-#string STR_VAR_POL_POLICY_NOT_FOUND #language en-US "%EVariable Policy Not Found for This Variable!%N\r\n"
-#string STR_VAR_POL_POLICY_UNEXP_ERR #language en-US "%EUnexpected Error Getting Policy Info!%N - %H%r%N\r\n"
-#string STR_VAR_POL_POLICY_HEADER_1 #language en-US "+-----------------------------------------------------------------------------+\r\n"
-#string STR_VAR_POL_POLICY_HEADER_2 #language en-US "| Variable Policy Info |\r\n"
-#string STR_VAR_POL_POLICY_VERSION #language en-US "| Version: 0x%-8x |\r\n"
-#string STR_VAR_POL_POLICY_VARIABLE #language en-US "| Variable: % -64s |\r\n"
-#string STR_VAR_POL_POLICY_NAMESPACE #language en-US "| Namespace: {%g} |\r\n"
-#string STR_VAR_POL_POLICY_MIN_SIZE #language en-US "| Minimum Size: 0x%-8x |\r\n"
-#string STR_VAR_POL_POLICY_MAX_SIZE #language en-US "| Maximum Size: 0x%-8x |\r\n"
-#string STR_VAR_POL_POLICY_ATTR_MUST #language en-US "| Required Attributes: |\r\n"
-#string STR_VAR_POL_POLICY_ATTR_NOT #language en-US "| Disallowed Attributes: |\r\n"
-#string STR_VAR_POL_POLICY_ATTR_GEN #language en-US "| %73-.73s |\r\n"
-#string STR_VAR_POL_POLICY_LOCK_TYPE #language en-US "| Lock Type: % -64s |\r\n"
-#string STR_VAR_POL_POLICY_STATE_NS #language en-US "| Namespace: {%g} |\r\n"
-#string STR_VAR_POL_POLICY_STATE_VAL #language en-US "| Value: 0x%-8x |\r\n"
-#string STR_VAR_POL_POLICY_STATE_NAME #language en-US "| Name: % -64s |\r\n"
-#string STR_VAR_POL_POLICY_STATS_PASS #language en-US " %V%d/%d UEFI variables have policy%N\r\n"
-#string STR_VAR_POL_POLICY_STATS_FAIL #language en-US " %E%d/%d UEFI variables have policy%N\r\n"
-
-#string STR_VAR_POL_VAR_TYPE #language en-US "%H% -70s%N\r\n"
-#string STR_VAR_POL_VAR_NAME #language en-US "Name: % -70s\r\n"
-#string STR_VAR_POL_VAR_SIZE #language en-US "Size: 0x%-16x (%-,d) bytes\r\n"
-#string STR_VAR_POL_VAR_ATTR #language en-US "Attributes: % -60s\r\n"
-
-#string STR_VAR_POL_STATS_HEADER_1 #language en-US "+----------------------------------------------------------------+\r\n"
-#string STR_VAR_POL_STATS_HEADER_2 #language en-US "| UEFI Variable Statistics |\r\n"
-#string STR_VAR_POL_STATS_TOTAL_VARS #language en-US " Total UEFI Variables: %,d\r\n"
-#string STR_VAR_POL_STATS_TOTAL_SIZE #language en-US " Total UEFI Variable Size: 0x%x (%,d) bytes\r\n"
-
-#string STR_GET_HELP_VAR_POLICY #language en-US ""
-".TH varpolicy 0 "Lists UEFI variable policy information."\r\n"
-".SH NAME\r\n"
-"Lists UEFI variable policy information.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"VARPOLICY [-p] [-s] [-v]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -p - The policy flag will print variable policy info for each variable.\r\n"
-" \r\n"
-" -s - The stats flag will print overall UEFI variable policy statistics.\r\n"
-" \r\n"
-" -v - The verbose flag indicates all known information should be printed.\r\n"
-" \r\n"
-" This includes a dump of the corresponding UEFI variable data in\r\n"
-" addition to all other UEFI variable policy information.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To dump all active UEFI variables:\r\n"
-" fs0:\> varpolicy\r\n"
-"\r\n"
-" * To include UEFI variable policy information:\r\n"
-" fs0:\> varpolicy -p\r\n"
-"\r\n"
-" * To include UEFI variable statistics:\r\n"
-" fs0:\> varpolicy -s\r\n"
-"\r\n"
-" * To include a hexadecimal dump of data for each variable\r\n"
-" and all other variable information:\r\n"
-" fs0:\> varpolicy -v\r\n"
+// /** +// String definitions for the Variable Policy ("varpolicy") shell command/app. +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +/=# + +#langdef en-US "english" + +// General Strings +#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n" +#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n" +#string STR_GEN_NO_VARS #language en-US "No UEFI variables found!\r\n" +#string STR_GEN_LINE_BREAK #language en-US "\r\n" + +#string STR_GEN_HEX_DUMP_LINE #language en-US "%B%08X%N: %-48a %V*%a*%N\r\n" + +#string STR_VAR_POL_POLICY_INT_ERR #language en-US "%EInternal Application Error Getting Policy Info!%N\r\n" +#string STR_VAR_POL_POLICY_NO_PROT #language en-US "%EVariable Policy Protocol Was Not Found!%N\r\n" +#string STR_VAR_POL_POLICY_NOT_INIT #language en-US "%EUEFI Variable Policy is Not Initialized!%N\r\n" +#string STR_VAR_POL_POLICY_NOT_FOUND #language en-US "%EVariable Policy Not Found for This Variable!%N\r\n" +#string STR_VAR_POL_POLICY_UNEXP_ERR #language en-US "%EUnexpected Error Getting Policy Info!%N - %H%r%N\r\n" +#string STR_VAR_POL_POLICY_HEADER_1 #language en-US "+-----------------------------------------------------------------------------+\r\n" +#string STR_VAR_POL_POLICY_HEADER_2 #language en-US "| Variable Policy Info |\r\n" +#string STR_VAR_POL_POLICY_VERSION #language en-US "| Version: 0x%-8x |\r\n" +#string STR_VAR_POL_POLICY_VARIABLE #language en-US "| Variable: % -64s |\r\n" +#string STR_VAR_POL_POLICY_NAMESPACE #language en-US "| Namespace: {%g} |\r\n" +#string STR_VAR_POL_POLICY_MIN_SIZE #language en-US "| Minimum Size: 0x%-8x |\r\n" +#string STR_VAR_POL_POLICY_MAX_SIZE #language en-US "| Maximum Size: 0x%-8x |\r\n" +#string STR_VAR_POL_POLICY_ATTR_MUST #language en-US "| Required Attributes: |\r\n" +#string STR_VAR_POL_POLICY_ATTR_NOT #language en-US "| Disallowed Attributes: |\r\n" +#string STR_VAR_POL_POLICY_ATTR_GEN #language en-US "| %73-.73s |\r\n" +#string STR_VAR_POL_POLICY_LOCK_TYPE #language en-US "| Lock Type: % -64s |\r\n" +#string STR_VAR_POL_POLICY_STATE_NS #language en-US "| Namespace: {%g} |\r\n" +#string STR_VAR_POL_POLICY_STATE_VAL #language en-US "| Value: 0x%-8x |\r\n" +#string STR_VAR_POL_POLICY_STATE_NAME #language en-US "| Name: % -64s |\r\n" +#string STR_VAR_POL_POLICY_STATS_PASS #language en-US " %V%d/%d UEFI variables have policy%N\r\n" +#string STR_VAR_POL_POLICY_STATS_FAIL #language en-US " %E%d/%d UEFI variables have policy%N\r\n" + +#string STR_VAR_POL_VAR_TYPE #language en-US "%H% -70s%N\r\n" +#string STR_VAR_POL_VAR_NAME #language en-US "Name: % -70s\r\n" +#string STR_VAR_POL_VAR_SIZE #language en-US "Size: 0x%-16x (%-,d) bytes\r\n" +#string STR_VAR_POL_VAR_ATTR #language en-US "Attributes: % -60s\r\n" + +#string STR_VAR_POL_STATS_HEADER_1 #language en-US "+----------------------------------------------------------------+\r\n" +#string STR_VAR_POL_STATS_HEADER_2 #language en-US "| UEFI Variable Statistics |\r\n" +#string STR_VAR_POL_STATS_TOTAL_VARS #language en-US " Total UEFI Variables: %,d\r\n" +#string STR_VAR_POL_STATS_TOTAL_SIZE #language en-US " Total UEFI Variable Size: 0x%x (%,d) bytes\r\n" + +#string STR_GET_HELP_VAR_POLICY #language en-US "" +".TH varpolicy 0 "Lists UEFI variable policy information."\r\n" +".SH NAME\r\n" +"Lists UEFI variable policy information.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"VARPOLICY [-p] [-s] [-v]\r\n" +".SH OPTIONS\r\n" +" \r\n" +" -p - The policy flag will print variable policy info for each variable.\r\n" +" \r\n" +" -s - The stats flag will print overall UEFI variable policy statistics.\r\n" +" \r\n" +" -v - The verbose flag indicates all known information should be printed.\r\n" +" \r\n" +" This includes a dump of the corresponding UEFI variable data in\r\n" +" addition to all other UEFI variable policy information.\r\n" +".SH DESCRIPTION\r\n" +" \r\n" +".SH EXAMPLES\r\n" +" \r\n" +"EXAMPLES:\r\n" +" * To dump all active UEFI variables:\r\n" +" fs0:\> varpolicy\r\n" +"\r\n" +" * To include UEFI variable policy information:\r\n" +" fs0:\> varpolicy -p\r\n" +"\r\n" +" * To include UEFI variable statistics:\r\n" +" fs0:\> varpolicy -s\r\n" +"\r\n" +" * To include a hexadecimal dump of data for each variable\r\n" +" and all other variable information:\r\n" +" fs0:\> varpolicy -v\r\n" diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.c index f3ab45de6a..4ea5599134 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.c +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.c @@ -1,59 +1,59 @@ -/** @file
- Functionality specific for standalone UEFI application support.
-
- This application can provide detailed UEFI variable policy configuration
- information in the UEFI shell.
-
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VariablePolicy.h"
-
-#include <Library/BaseLib.h>
-#include <Library/HiiLib.h>
-
-extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle;
-
-//
-// String token ID of help message text.
-// Shell supports finding the help message in the resource section of an
-// application image if a .MAN file is not found. This global variable is added
-// to make the build tool recognize that the help string is consumed by the user and
-// then the build tool will add the string into the resource section. Thus the
-// application can use '-?' option to show help message in Shell.
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_VAR_POLICY);
-
-/**
- Entry of the UEFI variable policy application.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS The application successfully initialized.
- @retval EFI_ABORTED The application failed to initialize.
- @retval Others A different error occurred.
-
-**/
-EFI_STATUS
-EFIAPI
-VariablePolicyAppInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mVarPolicyShellCommandHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mVarPolicyShellCommandHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = (EFI_STATUS)RunVarPolicy (ImageHandle, SystemTable);
-
- HiiRemovePackages (mVarPolicyShellCommandHiiHandle);
-
- return Status;
-}
+/** @file + Functionality specific for standalone UEFI application support. + + This application can provide detailed UEFI variable policy configuration + information in the UEFI shell. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VariablePolicy.h" + +#include <Library/BaseLib.h> +#include <Library/HiiLib.h> + +extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle; + +// +// String token ID of help message text. +// Shell supports finding the help message in the resource section of an +// application image if a .MAN file is not found. This global variable is added +// to make the build tool recognize that the help string is consumed by the user and +// then the build tool will add the string into the resource section. Thus the +// application can use '-?' option to show help message in Shell. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_VAR_POLICY); + +/** + Entry of the UEFI variable policy application. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS The application successfully initialized. + @retval EFI_ABORTED The application failed to initialize. + @retval Others A different error occurred. + +**/ +EFI_STATUS +EFIAPI +VariablePolicyAppInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mVarPolicyShellCommandHiiHandle = InitializeHiiPackage (ImageHandle); + if (mVarPolicyShellCommandHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = (EFI_STATUS)RunVarPolicy (ImageHandle, SystemTable); + + HiiRemovePackages (mVarPolicyShellCommandHiiHandle); + + return Status; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf index 1e8abe0923..55c25a94c9 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf @@ -1,62 +1,62 @@ -## @file
-# A UEFI variable policy application that displays information
-# about UEFI variable policy configuration on the system.
-#
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = varpolicy
- FILE_GUID = CA3D995F-3291-45AF-B50A-7C8AE584D857
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- ENTRY_POINT = VariablePolicyAppInitialize
- # Note: GetHelpText() in the EFI shell protocol will associate the help text
- # for the app if the app name (command) matches the .TH section name in
- # the Unicode help text. That name is "varpolicy".
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- VariablePolicy.uni
- VariablePolicy.h
- VariablePolicy.c
- VariablePolicyApp.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- HiiLib
- MemoryAllocationLib
- PrintLib
- ShellLib
- UefiApplicationEntryPoint
- UefiBootServicesTableLib
- UefiHiiServicesLib
- UefiRuntimeServicesTableLib
-
-[Protocols]
- gEdkiiVariablePolicyProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
-
-[Guids]
- ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace
- gEfiCapsuleReportGuid
- gEfiCapsuleVendorGuid
- gEfiGlobalVariableGuid
- gEfiMemoryOverwriteRequestControlLockGuid
- gEfiMemoryTypeInformationGuid
- gMtcVendorGuid
- gShellAliasGuid
- gShellVariableGuid
-
-[DEPEX]
- TRUE
+## @file +# A UEFI variable policy application that displays information +# about UEFI variable policy configuration on the system. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = varpolicy + FILE_GUID = CA3D995F-3291-45AF-B50A-7C8AE584D857 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VariablePolicyAppInitialize + # Note: GetHelpText() in the EFI shell protocol will associate the help text + # for the app if the app name (command) matches the .TH section name in + # the Unicode help text. That name is "varpolicy". + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + VariablePolicy.uni + VariablePolicy.h + VariablePolicy.c + VariablePolicyApp.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + HiiLib + MemoryAllocationLib + PrintLib + ShellLib + UefiApplicationEntryPoint + UefiBootServicesTableLib + UefiHiiServicesLib + UefiRuntimeServicesTableLib + +[Protocols] + gEdkiiVariablePolicyProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + +[Guids] + ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace + gEfiCapsuleReportGuid + gEfiCapsuleVendorGuid + gEfiGlobalVariableGuid + gEfiMemoryOverwriteRequestControlLockGuid + gEfiMemoryTypeInformationGuid + gMtcVendorGuid + gShellAliasGuid + gShellVariableGuid + +[DEPEX] + TRUE diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c index c1e309ad07..2a0dbc37c6 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c @@ -1,157 +1,157 @@ -/** @file
- Functionality specific for dynamic UEFI shell command support.
-
- This command can provide detailed UEFI variable policy configuration
- information in the UEFI shell.
-
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VariablePolicy.h"
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/HiiLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-
-#include <Protocol/ShellDynamicCommand.h>
-
-extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle;
-
-/**
- This is the shell command handler function pointer callback type.
-
- This function handles the command when it is invoked in the shell.
-
- @param[in] This The instance of the
- EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] SystemTable The pointer to the system table.
- @param[in] ShellParameters The parameters associated with the command.
- @param[in] Shell The instance of the shell protocol used in
- the context of processing this command.
-
- @return EFI_SUCCESS the operation was successful
- @return other the operation failed.
-
-**/
-SHELL_STATUS
-EFIAPI
-VarPolicyCommandHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- )
-{
- gEfiShellParametersProtocol = ShellParameters;
- gEfiShellProtocol = Shell;
-
- return RunVarPolicy (gImageHandle, SystemTable);
-}
-
-/**
- This is the command help handler function pointer callback type. This
- function is responsible for displaying help information for the associated
- command.
-
- @param[in] This The instance of the
- EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] Language The pointer to the language string to use.
-
- @return string Pool allocated help string, must be freed
- by caller.
-
-**/
-STATIC
-CHAR16 *
-EFIAPI
-VarPolicyCommandGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- )
-{
- return HiiGetString (
- mVarPolicyShellCommandHiiHandle,
- STRING_TOKEN (STR_GET_HELP_VAR_POLICY),
- Language
- );
-}
-
-STATIC EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mVarPolicyDynamicCommand = {
- VAR_POLICY_COMMAND_NAME,
- VarPolicyCommandHandler,
- VarPolicyCommandGetHelp
-};
-
-/**
- Entry point of the UEFI variable policy dynamic shell command.
-
- Produce the Dynamic Command Protocol to handle the "varpolicy" command.
-
- @param[in] ImageHandle The image handle of the process.
- @param[in] SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS The "varpolicy" command executed successfully.
- @retval EFI_ABORTED HII package failed to initialize.
- @retval others Other errors when executing "varpolicy" command.
-
-**/
-EFI_STATUS
-EFIAPI
-VariablePolicyDynamicCommandEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mVarPolicyShellCommandHiiHandle = InitializeHiiPackage (ImageHandle);
- if (mVarPolicyShellCommandHiiHandle == NULL) {
- return EFI_ABORTED;
- }
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mVarPolicyDynamicCommand
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
-
-/**
- Unload the dynamic "varpolicy" UEFI Shell command.
-
- @param[in] ImageHandle The image handle of the process.
-
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
-
-**/
-EFI_STATUS
-EFIAPI
-VariablePolicyDynamicCommandUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- Status = gBS->UninstallProtocolInterface (
- ImageHandle,
- &gEfiShellDynamicCommandProtocolGuid,
- &mVarPolicyDynamicCommand
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HiiRemovePackages (mVarPolicyShellCommandHiiHandle);
-
- return EFI_SUCCESS;
-}
+/** @file + Functionality specific for dynamic UEFI shell command support. + + This command can provide detailed UEFI variable policy configuration + information in the UEFI shell. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VariablePolicy.h" + +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/HiiLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> + +#include <Protocol/ShellDynamicCommand.h> + +extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle; + +/** + This is the shell command handler function pointer callback type. + + This function handles the command when it is invoked in the shell. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] SystemTable The pointer to the system table. + @param[in] ShellParameters The parameters associated with the command. + @param[in] Shell The instance of the shell protocol used in + the context of processing this command. + + @return EFI_SUCCESS the operation was successful + @return other the operation failed. + +**/ +SHELL_STATUS +EFIAPI +VarPolicyCommandHandler ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ) +{ + gEfiShellParametersProtocol = ShellParameters; + gEfiShellProtocol = Shell; + + return RunVarPolicy (gImageHandle, SystemTable); +} + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associated + command. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string to use. + + @return string Pool allocated help string, must be freed + by caller. + +**/ +STATIC +CHAR16 * +EFIAPI +VarPolicyCommandGetHelp ( + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ) +{ + return HiiGetString ( + mVarPolicyShellCommandHiiHandle, + STRING_TOKEN (STR_GET_HELP_VAR_POLICY), + Language + ); +} + +STATIC EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mVarPolicyDynamicCommand = { + VAR_POLICY_COMMAND_NAME, + VarPolicyCommandHandler, + VarPolicyCommandGetHelp +}; + +/** + Entry point of the UEFI variable policy dynamic shell command. + + Produce the Dynamic Command Protocol to handle the "varpolicy" command. + + @param[in] ImageHandle The image handle of the process. + @param[in] SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS The "varpolicy" command executed successfully. + @retval EFI_ABORTED HII package failed to initialize. + @retval others Other errors when executing "varpolicy" command. + +**/ +EFI_STATUS +EFIAPI +VariablePolicyDynamicCommandEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mVarPolicyShellCommandHiiHandle = InitializeHiiPackage (ImageHandle); + if (mVarPolicyShellCommandHiiHandle == NULL) { + return EFI_ABORTED; + } + + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + EFI_NATIVE_INTERFACE, + &mVarPolicyDynamicCommand + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Unload the dynamic "varpolicy" UEFI Shell command. + + @param[in] ImageHandle The image handle of the process. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. + +**/ +EFI_STATUS +EFIAPI +VariablePolicyDynamicCommandUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status = gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mVarPolicyDynamicCommand + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiRemovePackages (mVarPolicyShellCommandHiiHandle); + + return EFI_SUCCESS; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf index 120e7339da..6cd544a8f3 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf @@ -1,61 +1,61 @@ -## @file
-# A UEFI variable policy dynamic shell command that displays information
-# about UEFI variable policy configuration on the system.
-#
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 1.27
- BASE_NAME = VariablePolicyDynamicCommand
- FILE_GUID = 17D0EF2A-5933-4007-8950-5749169D3DC5
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = VariablePolicyDynamicCommandEntryPoint
- UNLOAD_IMAGE = VariablePolicyDynamicCommandUnload
- UEFI_HII_RESOURCE_SECTION = TRUE
-
-[Sources.common]
- VariablePolicy.uni
- VariablePolicy.h
- VariablePolicy.c
- VariablePolicyDynamicCommand.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- HiiLib
- MemoryAllocationLib
- PrintLib
- ShellLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiHiiServicesLib
- UefiRuntimeServicesTableLib
-
-[Protocols]
- gEdkiiVariablePolicyProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiPackageListProtocolGuid ## CONSUMES
- gEfiShellDynamicCommandProtocolGuid ## PRODUCES
-
-[Guids]
- ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace
- gEfiCapsuleReportGuid
- gEfiCapsuleVendorGuid
- gEfiGlobalVariableGuid
- gEfiMemoryOverwriteRequestControlLockGuid
- gEfiMemoryTypeInformationGuid
- gMtcVendorGuid
- gShellAliasGuid
- gShellVariableGuid
-
-[DEPEX]
- TRUE
+## @file +# A UEFI variable policy dynamic shell command that displays information +# about UEFI variable policy configuration on the system. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.27 + BASE_NAME = VariablePolicyDynamicCommand + FILE_GUID = 17D0EF2A-5933-4007-8950-5749169D3DC5 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = VariablePolicyDynamicCommandEntryPoint + UNLOAD_IMAGE = VariablePolicyDynamicCommandUnload + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources.common] + VariablePolicy.uni + VariablePolicy.h + VariablePolicy.c + VariablePolicyDynamicCommand.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + HiiLib + MemoryAllocationLib + PrintLib + ShellLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiHiiServicesLib + UefiRuntimeServicesTableLib + +[Protocols] + gEdkiiVariablePolicyProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + gEfiShellDynamicCommandProtocolGuid ## PRODUCES + +[Guids] + ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace + gEfiCapsuleReportGuid + gEfiCapsuleVendorGuid + gEfiGlobalVariableGuid + gEfiMemoryOverwriteRequestControlLockGuid + gEfiMemoryTypeInformationGuid + gMtcVendorGuid + gShellAliasGuid + gShellVariableGuid + +[DEPEX] + TRUE |
