diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib')
68 files changed, 41129 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Comp.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Comp.c new file mode 100644 index 00000000..a0d454ad --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Comp.c @@ -0,0 +1,493 @@ +/** @file + Main file for Comp shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-n", TypeValue}, + {L"-s", TypeValue}, + {NULL, TypeMax} + }; + +typedef enum { + OutOfDiffPoint, + InDiffPoint, + InPrevDiffPoint +} READ_STATUS; + +// +// Buffer type, for reading both file operands in chunks. +// +typedef struct { + UINT8 *Data; // dynamically allocated buffer + UINTN Allocated; // the allocated size of Data + UINTN Next; // next position in Data to fetch a byte at + UINTN Left; // number of bytes left in Data for fetching at Next +} FILE_BUFFER; + +/** + Function to print differnt point data. + + @param[in] FileName File name. + @param[in] FileTag File tag name. + @param[in] Buffer Data buffer to be printed. + @param[in] BufferSize Size of the data to be printed. + @param[in] Address Address of the differnt point. + @param[in] DifferentBytes Total size of the buffer. + +**/ +VOID +PrintDifferentPoint( + CONST CHAR16 *FileName, + CHAR16 *FileTag, + UINT8 *Buffer, + UINT64 BufferSize, + UINTN Address, + UINT64 DifferentBytes + ) +{ + UINTN Index; + + ShellPrintEx (-1, -1, L"%s: %s\r\n %08x:", FileTag, FileName, Address); + + // + // Print data in hex-format. + // + for (Index = 0; Index < BufferSize; Index++) { + ShellPrintEx (-1, -1, L" %02x", Buffer[Index]); + } + + if (BufferSize < DifferentBytes) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_END_OF_FILE), gShellDebug1HiiHandle); + } + + ShellPrintEx (-1, -1, L" *"); + + // + // Print data in char-format. + // + for (Index = 0; Index < BufferSize; Index++) { + if (Buffer[Index] >= 0x20 && Buffer[Index] <= 0x7E) { + ShellPrintEx (-1, -1, L"%c", Buffer[Index]); + } else { + // + // Print dots for control characters + // + ShellPrintEx (-1, -1, L"."); + } + } + + ShellPrintEx (-1, -1, L"*\r\n"); +} + +/** + Initialize a FILE_BUFFER. + + @param[out] FileBuffer The FILE_BUFFER to initialize. On return, the caller + is responsible for checking FileBuffer->Data: if + FileBuffer->Data is NULL on output, then memory + allocation failed. +**/ +STATIC +VOID +FileBufferInit ( + OUT FILE_BUFFER *FileBuffer + ) +{ + FileBuffer->Allocated = PcdGet32 (PcdShellFileOperationSize); + FileBuffer->Data = AllocatePool (FileBuffer->Allocated); + FileBuffer->Left = 0; +} + +/** + Uninitialize a FILE_BUFFER. + + @param[in,out] FileBuffer The FILE_BUFFER to uninitialize. The caller is + responsible for making sure FileBuffer was first + initialized with FileBufferInit(), successfully or + unsuccessfully. +**/ +STATIC +VOID +FileBufferUninit ( + IN OUT FILE_BUFFER *FileBuffer + ) +{ + SHELL_FREE_NON_NULL (FileBuffer->Data); +} + +/** + Read a byte from a SHELL_FILE_HANDLE, buffered with a FILE_BUFFER. + + @param[in] FileHandle The SHELL_FILE_HANDLE to replenish FileBuffer + from, if needed. + + @param[in,out] FileBuffer The FILE_BUFFER to read a byte from. If FileBuffer + is empty on entry, then FileBuffer is refilled + from FileHandle, before outputting a byte from + FileBuffer to Byte. The caller is responsible for + ensuring that FileBuffer was successfully + initialized with FileBufferInit(). + + @param[out] BytesRead On successful return, BytesRead is set to 1 if the + next byte from FileBuffer has been stored to Byte. + On successful return, BytesRead is set to 0 if + FileBuffer is empty, and FileHandle is at EOF. + When an error is returned, BytesRead is not set. + + @param[out] Byte On output, the next byte from FileBuffer. Only set + if (a) EFI_SUCCESS is returned and (b) BytesRead + is set to 1 on output. + + @retval EFI_SUCCESS BytesRead has been set to 0 or 1. In the latter case, + Byte has been set as well. + + @return Error codes propagated from + gEfiShellProtocol->ReadFile(). +**/ +STATIC +EFI_STATUS +FileBufferReadByte ( + IN SHELL_FILE_HANDLE FileHandle, + IN OUT FILE_BUFFER *FileBuffer, + OUT UINTN *BytesRead, + OUT UINT8 *Byte + ) +{ + UINTN ReadSize; + EFI_STATUS Status; + + if (FileBuffer->Left == 0) { + ReadSize = FileBuffer->Allocated; + Status = gEfiShellProtocol->ReadFile (FileHandle, &ReadSize, + FileBuffer->Data); + if (EFI_ERROR (Status)) { + return Status; + } + if (ReadSize == 0) { + *BytesRead = 0; + return EFI_SUCCESS; + } + FileBuffer->Next = 0; + FileBuffer->Left = ReadSize; + } + + *BytesRead = 1; + *Byte = FileBuffer->Data[FileBuffer->Next]; + + FileBuffer->Next++; + FileBuffer->Left--; + return EFI_SUCCESS; +} + +/** + Function for 'comp' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunComp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CHAR16 *FileName1; + CHAR16 *FileName2; + CONST CHAR16 *TempParam; + SHELL_STATUS ShellStatus; + SHELL_FILE_HANDLE FileHandle1; + SHELL_FILE_HANDLE FileHandle2; + UINT64 Size1; + UINT64 Size2; + UINT64 DifferentBytes; + UINT64 DifferentCount; + UINT8 DiffPointNumber; + UINT8 OneByteFromFile1; + UINT8 OneByteFromFile2; + UINT8 *DataFromFile1; + UINT8 *DataFromFile2; + FILE_BUFFER FileBuffer1; + FILE_BUFFER FileBuffer2; + UINTN InsertPosition1; + UINTN InsertPosition2; + UINTN DataSizeFromFile1; + UINTN DataSizeFromFile2; + UINTN TempAddress; + UINTN Index; + UINTN DiffPointAddress; + READ_STATUS ReadStatus; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + FileName1 = NULL; + FileName2 = NULL; + FileHandle1 = NULL; + FileHandle2 = NULL; + DataFromFile1 = NULL; + DataFromFile2 = NULL; + ReadStatus = OutOfDiffPoint; + DifferentCount = 10; + DifferentBytes = 4; + DiffPointNumber = 0; + InsertPosition1 = 0; + InsertPosition2 = 0; + TempAddress = 0; + DiffPointAddress = 0; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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), gShellDebug1HiiHandle, L"comp", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"comp"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) < 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"comp"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + TempParam = ShellCommandLineGetRawValue(Package, 1); + ASSERT(TempParam != NULL); + FileName1 = ShellFindFilePath(TempParam); + if (FileName1 == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } else { + Status = ShellOpenFileByName(FileName1, &FileHandle1, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } + } + TempParam = ShellCommandLineGetRawValue(Package, 2); + ASSERT(TempParam != NULL); + FileName2 = ShellFindFilePath(TempParam); + if (FileName2 == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } else { + Status = ShellOpenFileByName(FileName2, &FileHandle2, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } + } + if (ShellStatus == SHELL_SUCCESS) { + Status = gEfiShellProtocol->GetFileSize(FileHandle1, &Size1); + ASSERT_EFI_ERROR(Status); + Status = gEfiShellProtocol->GetFileSize(FileHandle2, &Size2); + ASSERT_EFI_ERROR(Status); + + if (ShellCommandLineGetFlag (Package, L"-n")) { + TempParam = ShellCommandLineGetValue (Package, L"-n"); + if (TempParam == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-n"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempParam, L"all") == 0) { + DifferentCount = MAX_UINTN; + } else { + Status = ShellConvertStringToUint64 (TempParam, &DifferentCount, FALSE, TRUE); + if (EFI_ERROR(Status) || DifferentCount == 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-n"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } + } + + if (ShellCommandLineGetFlag (Package, L"-s")) { + TempParam = ShellCommandLineGetValue (Package, L"-s"); + if (TempParam == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellConvertStringToUint64 (TempParam, &DifferentBytes, FALSE, TRUE); + if (EFI_ERROR(Status) || DifferentBytes == 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (DifferentBytes > MAX (Size1, Size2)) { + DifferentBytes = MAX (Size1, Size2); + } + } + } + } + } + + if (ShellStatus == SHELL_SUCCESS) { + DataFromFile1 = AllocateZeroPool ((UINTN)DifferentBytes); + DataFromFile2 = AllocateZeroPool ((UINTN)DifferentBytes); + FileBufferInit (&FileBuffer1); + FileBufferInit (&FileBuffer2); + if (DataFromFile1 == NULL || DataFromFile2 == NULL || + FileBuffer1.Data == NULL || FileBuffer2.Data == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + SHELL_FREE_NON_NULL (DataFromFile1); + SHELL_FREE_NON_NULL (DataFromFile2); + FileBufferUninit (&FileBuffer1); + FileBufferUninit (&FileBuffer2); + } + } + + if (ShellStatus == SHELL_SUCCESS) { + while (DiffPointNumber < DifferentCount) { + DataSizeFromFile1 = 1; + DataSizeFromFile2 = 1; + OneByteFromFile1 = 0; + OneByteFromFile2 = 0; + Status = FileBufferReadByte (FileHandle1, &FileBuffer1, + &DataSizeFromFile1, &OneByteFromFile1); + ASSERT_EFI_ERROR (Status); + Status = FileBufferReadByte (FileHandle2, &FileBuffer2, + &DataSizeFromFile2, &OneByteFromFile2); + ASSERT_EFI_ERROR (Status); + + TempAddress++; + + // + // 1.When end of file and no chars in DataFromFile buffer, then break while. + // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever. + // So the previous different point is the last one, then break the while block. + // + if ( (DataSizeFromFile1 == 0 && InsertPosition1 == 0 && DataSizeFromFile2 == 0 && InsertPosition2 == 0) || + (ReadStatus == InPrevDiffPoint && (DataSizeFromFile1 == 0 || DataSizeFromFile2 == 0)) + ) { + break; + } + + if (ReadStatus == OutOfDiffPoint) { + if (OneByteFromFile1 != OneByteFromFile2) { + ReadStatus = InDiffPoint; + DiffPointAddress = TempAddress; + if (DataSizeFromFile1 == 1) { + DataFromFile1[InsertPosition1++] = OneByteFromFile1; + } + if (DataSizeFromFile2 == 1) { + DataFromFile2[InsertPosition2++] = OneByteFromFile2; + } + } + } else if (ReadStatus == InDiffPoint) { + if (DataSizeFromFile1 == 1) { + DataFromFile1[InsertPosition1++] = OneByteFromFile1; + } + if (DataSizeFromFile2 == 1) { + DataFromFile2[InsertPosition2++] = OneByteFromFile2; + } + } else if (ReadStatus == InPrevDiffPoint) { + if (OneByteFromFile1 == OneByteFromFile2) { + ReadStatus = OutOfDiffPoint; + } + } + + // + // ReadStatus should be always equal InDiffPoint. + // + if ( InsertPosition1 == DifferentBytes || + InsertPosition2 == DifferentBytes || + (DataSizeFromFile1 == 0 && DataSizeFromFile2 == 0) + ) { + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT), gShellDebug1HiiHandle, ++DiffPointNumber); + PrintDifferentPoint (FileName1, L"File1", DataFromFile1, InsertPosition1, DiffPointAddress, DifferentBytes); + PrintDifferentPoint (FileName2, L"File2", DataFromFile2, InsertPosition2, DiffPointAddress, DifferentBytes); + + // + // One of two buffuers is empty, it means this is the last different point. + // + if (InsertPosition1 == 0 || InsertPosition2 == 0) { + break; + } + + for (Index = 1; Index < InsertPosition1 && Index < InsertPosition2; Index++) { + if (DataFromFile1[Index] == DataFromFile2[Index]) { + ReadStatus = OutOfDiffPoint; + break; + } + } + + if (ReadStatus == OutOfDiffPoint) { + // + // Try to find a new different point in the rest of DataFromFile. + // + for (; Index < MAX (InsertPosition1,InsertPosition2); Index++) { + if (DataFromFile1[Index] != DataFromFile2[Index]) { + ReadStatus = InDiffPoint; + DiffPointAddress += Index; + break; + } + } + } else { + // + // Doesn't find a new different point, still in the same different point. + // + ReadStatus = InPrevDiffPoint; + } + + CopyMem (DataFromFile1, DataFromFile1 + Index, InsertPosition1 - Index); + CopyMem (DataFromFile2, DataFromFile2 + Index, InsertPosition2 - Index); + + SetMem (DataFromFile1 + InsertPosition1 - Index, (UINTN)DifferentBytes - InsertPosition1 + Index, 0); + SetMem (DataFromFile2 + InsertPosition2 - Index, (UINTN)DifferentBytes - InsertPosition2 + Index, 0); + + InsertPosition1 -= Index; + InsertPosition2 -= Index; + } + } + + SHELL_FREE_NON_NULL (DataFromFile1); + SHELL_FREE_NON_NULL (DataFromFile2); + FileBufferUninit (&FileBuffer1); + FileBufferUninit (&FileBuffer2); + + if (DiffPointNumber == 0) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_PASS), gShellDebug1HiiHandle); + } else { + ShellStatus = SHELL_NOT_EQUAL; + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_FAIL), gShellDebug1HiiHandle); + } + } + } + + ShellCommandLineFreeVarList (Package); + } + SHELL_FREE_NON_NULL(FileName1); + SHELL_FREE_NON_NULL(FileName2); + + if (FileHandle1 != NULL) { + gEfiShellProtocol->CloseFile(FileHandle1); + } + if (FileHandle2 != NULL) { + gEfiShellProtocol->CloseFile(FileHandle2); + } + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.c new file mode 100644 index 00000000..6b263535 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.c @@ -0,0 +1,1382 @@ +/** @file + Main file for compression routine. + + Compression routine. The compression algorithm is a mixture of + LZ77 and Huffman coding. LZ77 transforms the source data into a + sequence of Original Characters and Pointers to repeated strings. + This sequence is further divided into Blocks and Huffman codings + are applied to each Block. + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include <Uefi.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/ShellLib.h> + +#include "Compress.h" + +// +// Macro Definitions +// +typedef INT16 NODE; +#define UINT8_MAX 0xff +#define UINT8_BIT 8 +#define THRESHOLD 3 +#define INIT_CRC 0 +#define WNDBIT 13 +#define WNDSIZ (1U << WNDBIT) +#define MAXMATCH 256 +#define BLKSIZ (1U << 14) // 16 * 1024U +#define PERC_FLAG 0x8000U +#define CODE_BIT 16 +#define NIL 0 +#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX) +#define HASH(LoopVar7, LoopVar5) ((LoopVar7) + ((LoopVar5) << (WNDBIT - 9)) + WNDSIZ * 2) +#define CRCPOLY 0xA001 +#define UPDATE_CRC(LoopVar5) mCrc = mCrcTable[(mCrc ^ (LoopVar5)) & 0xFF] ^ (mCrc >> UINT8_BIT) + +// +// C: the Char&Len Set; P: the Position Set; T: the exTra Set +// +#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD) +#define CBIT 9 +#define NP (WNDBIT + 1) +#define PBIT 4 +#define NT (CODE_BIT + 3) +#define TBIT 5 +#if NT > NP + #define NPT NT +#else + #define NPT NP +#endif +// +// Function Prototypes +// + +/** + Put a dword to output stream + + @param[in] Data The dword to put. +**/ +VOID +PutDword( + IN UINT32 Data + ); + +// +// Global Variables +// +STATIC UINT8 *mSrc; +STATIC UINT8 *mDst; +STATIC UINT8 *mSrcUpperLimit; +STATIC UINT8 *mDstUpperLimit; + +STATIC UINT8 *mLevel; +STATIC UINT8 *mText; +STATIC UINT8 *mChildCount; +STATIC UINT8 *mBuf; +STATIC UINT8 mCLen[NC]; +STATIC UINT8 mPTLen[NPT]; +STATIC UINT8 *mLen; +STATIC INT16 mHeap[NC + 1]; +STATIC INT32 mRemainder; +STATIC INT32 mMatchLen; +STATIC INT32 mBitCount; +STATIC INT32 mHeapSize; +STATIC INT32 mTempInt32; +STATIC UINT32 mBufSiz = 0; +STATIC UINT32 mOutputPos; +STATIC UINT32 mOutputMask; +STATIC UINT32 mSubBitBuf; +STATIC UINT32 mCrc; +STATIC UINT32 mCompSize; +STATIC UINT32 mOrigSize; + +STATIC UINT16 *mFreq; +STATIC UINT16 *mSortPtr; +STATIC UINT16 mLenCnt[17]; +STATIC UINT16 mLeft[2 * NC - 1]; +STATIC UINT16 mRight[2 * NC - 1]; +STATIC UINT16 mCrcTable[UINT8_MAX + 1]; +STATIC UINT16 mCFreq[2 * NC - 1]; +STATIC UINT16 mCCode[NC]; +STATIC UINT16 mPFreq[2 * NP - 1]; +STATIC UINT16 mPTCode[NPT]; +STATIC UINT16 mTFreq[2 * NT - 1]; + +STATIC NODE mPos; +STATIC NODE mMatchPos; +STATIC NODE mAvail; +STATIC NODE *mPosition; +STATIC NODE *mParent; +STATIC NODE *mPrev; +STATIC NODE *mNext = NULL; +INT32 mHuffmanDepth = 0; + +/** + Make a CRC table. + +**/ +VOID +MakeCrcTable ( + VOID + ) +{ + UINT32 LoopVar1; + + UINT32 LoopVar2; + + UINT32 LoopVar4; + + for (LoopVar1 = 0; LoopVar1 <= UINT8_MAX; LoopVar1++) { + LoopVar4 = LoopVar1; + for (LoopVar2 = 0; LoopVar2 < UINT8_BIT; LoopVar2++) { + if ((LoopVar4 & 1) != 0) { + LoopVar4 = (LoopVar4 >> 1) ^ CRCPOLY; + } else { + LoopVar4 >>= 1; + } + } + + mCrcTable[LoopVar1] = (UINT16) LoopVar4; + } +} + +/** + Put a dword to output stream + + @param[in] Data The dword to put. +**/ +VOID +PutDword ( + IN UINT32 Data + ) +{ + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff); + } +} + +/** + Allocate memory spaces for data structures used in compression process. + + @retval EFI_SUCCESS Memory was allocated successfully. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +AllocateMemory ( + VOID + ) +{ + mText = AllocateZeroPool (WNDSIZ * 2 + MAXMATCH); + mLevel = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel)); + mChildCount = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount)); + mPosition = AllocateZeroPool ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition)); + mParent = AllocateZeroPool (WNDSIZ * 2 * sizeof (*mParent)); + mPrev = AllocateZeroPool (WNDSIZ * 2 * sizeof (*mPrev)); + mNext = AllocateZeroPool ((MAX_HASH_VAL + 1) * sizeof (*mNext)); + + mBufSiz = BLKSIZ; + mBuf = AllocateZeroPool (mBufSiz); + while (mBuf == NULL) { + mBufSiz = (mBufSiz / 10U) * 9U; + if (mBufSiz < 4 * 1024U) { + return EFI_OUT_OF_RESOURCES; + } + + mBuf = AllocateZeroPool (mBufSiz); + } + + mBuf[0] = 0; + + return EFI_SUCCESS; +} + +/** + Called when compression is completed to free memory previously allocated. + +**/ +VOID +FreeMemory ( + VOID + ) +{ + SHELL_FREE_NON_NULL (mText); + SHELL_FREE_NON_NULL (mLevel); + SHELL_FREE_NON_NULL (mChildCount); + SHELL_FREE_NON_NULL (mPosition); + SHELL_FREE_NON_NULL (mParent); + SHELL_FREE_NON_NULL (mPrev); + SHELL_FREE_NON_NULL (mNext); + SHELL_FREE_NON_NULL (mBuf); +} + +/** + Initialize String Info Log data structures. +**/ +VOID +InitSlide ( + VOID + ) +{ + NODE LoopVar1; + + SetMem (mLevel + WNDSIZ, (UINT8_MAX + 1) * sizeof (UINT8), 1); + SetMem (mPosition + WNDSIZ, (UINT8_MAX + 1) * sizeof (NODE), 0); + + SetMem (mParent + WNDSIZ, WNDSIZ * sizeof (NODE), 0); + + mAvail = 1; + for (LoopVar1 = 1; LoopVar1 < WNDSIZ - 1; LoopVar1++) { + mNext[LoopVar1] = (NODE) (LoopVar1 + 1); + } + + mNext[WNDSIZ - 1] = NIL; + SetMem (mNext + WNDSIZ * 2, (MAX_HASH_VAL - WNDSIZ * 2 + 1) * sizeof (NODE), 0); +} + +/** + Find child node given the parent node and the edge character + + @param[in] LoopVar6 The parent node. + @param[in] LoopVar5 The edge character. + + @return The child node. + @retval NIL(Zero) No child could be found. + +**/ +NODE +Child ( + IN NODE LoopVar6, + IN UINT8 LoopVar5 + ) +{ + NODE LoopVar4; + + LoopVar4 = mNext[HASH (LoopVar6, LoopVar5)]; + mParent[NIL] = LoopVar6; /* sentinel */ + while (mParent[LoopVar4] != LoopVar6) { + LoopVar4 = mNext[LoopVar4]; + } + + return LoopVar4; +} + +/** + Create a new child for a given parent node. + + @param[in] LoopVar6 The parent node. + @param[in] LoopVar5 The edge character. + @param[in] LoopVar4 The child node. +**/ +VOID +MakeChild ( + IN NODE LoopVar6, + IN UINT8 LoopVar5, + IN NODE LoopVar4 + ) +{ + NODE LoopVar12; + + NODE LoopVar10; + + LoopVar12 = (NODE) HASH (LoopVar6, LoopVar5); + LoopVar10 = mNext[LoopVar12]; + mNext[LoopVar12] = LoopVar4; + mNext[LoopVar4] = LoopVar10; + mPrev[LoopVar10] = LoopVar4; + mPrev[LoopVar4] = LoopVar12; + mParent[LoopVar4] = LoopVar6; + mChildCount[LoopVar6]++; +} + +/** + Split a node. + + @param[in] Old The node to split. +**/ +VOID +Split ( + IN NODE Old + ) +{ + NODE New; + + NODE LoopVar10; + + New = mAvail; + mAvail = mNext[New]; + mChildCount[New] = 0; + LoopVar10 = mPrev[Old]; + mPrev[New] = LoopVar10; + mNext[LoopVar10] = New; + LoopVar10 = mNext[Old]; + mNext[New] = LoopVar10; + mPrev[LoopVar10] = New; + mParent[New] = mParent[Old]; + mLevel[New] = (UINT8) mMatchLen; + mPosition[New] = mPos; + MakeChild (New, mText[mMatchPos + mMatchLen], Old); + MakeChild (New, mText[mPos + mMatchLen], mPos); +} + +/** + Insert string info for current position into the String Info Log. + +**/ +VOID +InsertNode ( + VOID + ) +{ + NODE LoopVar6; + + NODE LoopVar4; + + NODE LoopVar2; + + NODE LoopVar10; + UINT8 LoopVar5; + UINT8 *TempString3; + UINT8 *TempString2; + + if (mMatchLen >= 4) { + // + // We have just got a long match, the target tree + // can be located by MatchPos + 1. Travese the tree + // from bottom up to get to a proper starting point. + // The usage of PERC_FLAG ensures proper node deletion + // in DeleteNode() later. + // + mMatchLen--; + LoopVar4 = (NODE) ((mMatchPos + 1) | WNDSIZ); + LoopVar6 = mParent[LoopVar4]; + while (LoopVar6 == NIL) { + LoopVar4 = mNext[LoopVar4]; + LoopVar6 = mParent[LoopVar4]; + } + + while (mLevel[LoopVar6] >= mMatchLen) { + LoopVar4 = LoopVar6; + LoopVar6 = mParent[LoopVar6]; + } + + LoopVar10 = LoopVar6; + while (mPosition[LoopVar10] < 0) { + mPosition[LoopVar10] = mPos; + LoopVar10 = mParent[LoopVar10]; + } + + if (LoopVar10 < WNDSIZ) { + mPosition[LoopVar10] = (NODE) (mPos | PERC_FLAG); + } + } else { + // + // Locate the target tree + // + LoopVar6 = (NODE) (mText[mPos] + WNDSIZ); + LoopVar5 = mText[mPos + 1]; + LoopVar4 = Child (LoopVar6, LoopVar5); + if (LoopVar4 == NIL) { + MakeChild (LoopVar6, LoopVar5, mPos); + mMatchLen = 1; + return ; + } + + mMatchLen = 2; + } + // + // Traverse down the tree to find a match. + // Update Position value along the route. + // Node split or creation is involved. + // + for (;;) { + if (LoopVar4 >= WNDSIZ) { + LoopVar2 = MAXMATCH; + mMatchPos = LoopVar4; + } else { + LoopVar2 = mLevel[LoopVar4]; + mMatchPos = (NODE) (mPosition[LoopVar4] & ~PERC_FLAG); + } + + if (mMatchPos >= mPos) { + mMatchPos -= WNDSIZ; + } + + TempString3 = &mText[mPos + mMatchLen]; + TempString2 = &mText[mMatchPos + mMatchLen]; + while (mMatchLen < LoopVar2) { + if (*TempString3 != *TempString2) { + Split (LoopVar4); + return ; + } + + mMatchLen++; + TempString3++; + TempString2++; + } + + if (mMatchLen >= MAXMATCH) { + break; + } + + mPosition[LoopVar4] = mPos; + LoopVar6 = LoopVar4; + LoopVar4 = Child (LoopVar6, *TempString3); + if (LoopVar4 == NIL) { + MakeChild (LoopVar6, *TempString3, mPos); + return ; + } + + mMatchLen++; + } + + LoopVar10 = mPrev[LoopVar4]; + mPrev[mPos] = LoopVar10; + mNext[LoopVar10] = mPos; + LoopVar10 = mNext[LoopVar4]; + mNext[mPos] = LoopVar10; + mPrev[LoopVar10] = mPos; + mParent[mPos] = LoopVar6; + mParent[LoopVar4] = NIL; + + // + // Special usage of 'next' + // + mNext[LoopVar4] = mPos; + +} + +/** + Delete outdated string info. (The Usage of PERC_FLAG + ensures a clean deletion). + +**/ +VOID +DeleteNode ( + VOID + ) +{ + NODE LoopVar6; + + NODE LoopVar4; + + NODE LoopVar11; + + NODE LoopVar10; + + NODE LoopVar9; + + if (mParent[mPos] == NIL) { + return ; + } + + LoopVar4 = mPrev[mPos]; + LoopVar11 = mNext[mPos]; + mNext[LoopVar4] = LoopVar11; + mPrev[LoopVar11] = LoopVar4; + LoopVar4 = mParent[mPos]; + mParent[mPos] = NIL; + if (LoopVar4 >= WNDSIZ) { + return ; + } + + mChildCount[LoopVar4]--; + if (mChildCount[LoopVar4] > 1) { + return ; + } + + LoopVar10 = (NODE) (mPosition[LoopVar4] & ~PERC_FLAG); + if (LoopVar10 >= mPos) { + LoopVar10 -= WNDSIZ; + } + + LoopVar11 = LoopVar10; + LoopVar6 = mParent[LoopVar4]; + LoopVar9 = mPosition[LoopVar6]; + while ((LoopVar9 & PERC_FLAG) != 0){ + LoopVar9 &= ~PERC_FLAG; + if (LoopVar9 >= mPos) { + LoopVar9 -= WNDSIZ; + } + + if (LoopVar9 > LoopVar11) { + LoopVar11 = LoopVar9; + } + + mPosition[LoopVar6] = (NODE) (LoopVar11 | WNDSIZ); + LoopVar6 = mParent[LoopVar6]; + LoopVar9 = mPosition[LoopVar6]; + } + + if (LoopVar6 < WNDSIZ) { + if (LoopVar9 >= mPos) { + LoopVar9 -= WNDSIZ; + } + + if (LoopVar9 > LoopVar11) { + LoopVar11 = LoopVar9; + } + + mPosition[LoopVar6] = (NODE) (LoopVar11 | WNDSIZ | PERC_FLAG); + } + + LoopVar11 = Child (LoopVar4, mText[LoopVar10 + mLevel[LoopVar4]]); + LoopVar10 = mPrev[LoopVar11]; + LoopVar9 = mNext[LoopVar11]; + mNext[LoopVar10] = LoopVar9; + mPrev[LoopVar9] = LoopVar10; + LoopVar10 = mPrev[LoopVar4]; + mNext[LoopVar10] = LoopVar11; + mPrev[LoopVar11] = LoopVar10; + LoopVar10 = mNext[LoopVar4]; + mPrev[LoopVar10] = LoopVar11; + mNext[LoopVar11] = LoopVar10; + mParent[LoopVar11] = mParent[LoopVar4]; + mParent[LoopVar4] = NIL; + mNext[LoopVar4] = mAvail; + mAvail = LoopVar4; +} + +/** + Read in source data + + @param[out] LoopVar7 The buffer to hold the data. + @param[in] LoopVar8 The number of bytes to read. + + @return The number of bytes actually read. +**/ +INT32 +FreadCrc ( + OUT UINT8 *LoopVar7, + IN INT32 LoopVar8 + ) +{ + INT32 LoopVar1; + + for (LoopVar1 = 0; mSrc < mSrcUpperLimit && LoopVar1 < LoopVar8; LoopVar1++) { + *LoopVar7++ = *mSrc++; + } + + LoopVar8 = LoopVar1; + + LoopVar7 -= LoopVar8; + mOrigSize += LoopVar8; + LoopVar1--; + while (LoopVar1 >= 0) { + UPDATE_CRC (*LoopVar7++); + LoopVar1--; + } + + return LoopVar8; +} + +/** + Advance the current position (read in new data if needed). + Delete outdated string info. Find a match string for current position. + + @retval TRUE The operation was successful. + @retval FALSE The operation failed due to insufficient memory. +**/ +BOOLEAN +GetNextMatch ( + VOID + ) +{ + INT32 LoopVar8; + VOID *Temp; + + mRemainder--; + mPos++; + if (mPos == WNDSIZ * 2) { + Temp = AllocateZeroPool (WNDSIZ + MAXMATCH); + if (Temp == NULL) { + return (FALSE); + } + CopyMem (Temp, &mText[WNDSIZ], WNDSIZ + MAXMATCH); + CopyMem (&mText[0], Temp, WNDSIZ + MAXMATCH); + FreePool (Temp); + LoopVar8 = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ); + mRemainder += LoopVar8; + mPos = WNDSIZ; + } + + DeleteNode (); + InsertNode (); + + return (TRUE); +} + +/** + Send entry LoopVar1 down the queue. + + @param[in] LoopVar1 The index of the item to move. +**/ +VOID +DownHeap ( + IN INT32 i + ) +{ + INT32 LoopVar1; + + INT32 LoopVar2; + + // + // priority queue: send i-th entry down heap + // + LoopVar2 = mHeap[i]; + LoopVar1 = 2 * i; + while (LoopVar1 <= mHeapSize) { + if (LoopVar1 < mHeapSize && mFreq[mHeap[LoopVar1]] > mFreq[mHeap[LoopVar1 + 1]]) { + LoopVar1++; + } + + if (mFreq[LoopVar2] <= mFreq[mHeap[LoopVar1]]) { + break; + } + + mHeap[i] = mHeap[LoopVar1]; + i = LoopVar1; + LoopVar1 = 2 * i; + } + + mHeap[i] = (INT16) LoopVar2; +} + +/** + Count the number of each code length for a Huffman tree. + + @param[in] LoopVar1 The top node. +**/ +VOID +CountLen ( + IN INT32 LoopVar1 + ) +{ + if (LoopVar1 < mTempInt32) { + mLenCnt[(mHuffmanDepth < 16) ? mHuffmanDepth : 16]++; + } else { + mHuffmanDepth++; + CountLen (mLeft[LoopVar1]); + CountLen (mRight[LoopVar1]); + mHuffmanDepth--; + } +} + +/** + Create code length array for a Huffman tree. + + @param[in] Root The root of the tree. +**/ +VOID +MakeLen ( + IN INT32 Root + ) +{ + INT32 LoopVar1; + + INT32 LoopVar2; + UINT32 Cum; + + for (LoopVar1 = 0; LoopVar1 <= 16; LoopVar1++) { + mLenCnt[LoopVar1] = 0; + } + + CountLen (Root); + + // + // Adjust the length count array so that + // no code will be generated longer than its designated length + // + Cum = 0; + for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) { + Cum += mLenCnt[LoopVar1] << (16 - LoopVar1); + } + + while (Cum != (1U << 16)) { + mLenCnt[16]--; + for (LoopVar1 = 15; LoopVar1 > 0; LoopVar1--) { + if (mLenCnt[LoopVar1] != 0) { + mLenCnt[LoopVar1]--; + mLenCnt[LoopVar1 + 1] += 2; + break; + } + } + + Cum--; + } + + for (LoopVar1 = 16; LoopVar1 > 0; LoopVar1--) { + LoopVar2 = mLenCnt[LoopVar1]; + LoopVar2--; + while (LoopVar2 >= 0) { + mLen[*mSortPtr++] = (UINT8) LoopVar1; + LoopVar2--; + } + } +} + +/** + Assign code to each symbol based on the code length array. + + @param[in] LoopVar8 The number of symbols. + @param[in] Len The code length array. + @param[out] Code The stores codes for each symbol. +**/ +VOID +MakeCode ( + IN INT32 LoopVar8, + IN UINT8 Len[ ], + OUT UINT16 Code[ ] + ) +{ + INT32 LoopVar1; + UINT16 Start[18]; + + Start[1] = 0; + for (LoopVar1 = 1; LoopVar1 <= 16; LoopVar1++) { + Start[LoopVar1 + 1] = (UINT16) ((Start[LoopVar1] + mLenCnt[LoopVar1]) << 1); + } + + for (LoopVar1 = 0; LoopVar1 < LoopVar8; LoopVar1++) { + Code[LoopVar1] = Start[Len[LoopVar1]]++; + } +} + +/** + Generates Huffman codes given a frequency distribution of symbols. + + @param[in] NParm The number of symbols. + @param[in] FreqParm The frequency of each symbol. + @param[out] LenParm The code length for each symbol. + @param[out] CodeParm The code for each symbol. + + @return The root of the Huffman tree. +**/ +INT32 +MakeTree ( + IN INT32 NParm, + IN UINT16 FreqParm[ ], + OUT UINT8 LenParm[ ], + OUT UINT16 CodeParm[ ] + ) +{ + INT32 LoopVar1; + + INT32 LoopVar2; + + INT32 LoopVar3; + + INT32 Avail; + + // + // make tree, calculate len[], return root + // + mTempInt32 = NParm; + mFreq = FreqParm; + mLen = LenParm; + Avail = mTempInt32; + mHeapSize = 0; + mHeap[1] = 0; + for (LoopVar1 = 0; LoopVar1 < mTempInt32; LoopVar1++) { + mLen[LoopVar1] = 0; + if ((mFreq[LoopVar1]) != 0) { + mHeapSize++; + mHeap[mHeapSize] = (INT16) LoopVar1; + } + } + + if (mHeapSize < 2) { + CodeParm[mHeap[1]] = 0; + return mHeap[1]; + } + + for (LoopVar1 = mHeapSize / 2; LoopVar1 >= 1; LoopVar1--) { + // + // make priority queue + // + DownHeap (LoopVar1); + } + + mSortPtr = CodeParm; + do { + LoopVar1 = mHeap[1]; + if (LoopVar1 < mTempInt32) { + *mSortPtr++ = (UINT16) LoopVar1; + } + + mHeap[1] = mHeap[mHeapSize--]; + DownHeap (1); + LoopVar2 = mHeap[1]; + if (LoopVar2 < mTempInt32) { + *mSortPtr++ = (UINT16) LoopVar2; + } + + LoopVar3 = Avail++; + mFreq[LoopVar3] = (UINT16) (mFreq[LoopVar1] + mFreq[LoopVar2]); + mHeap[1] = (INT16) LoopVar3; + DownHeap (1); + mLeft[LoopVar3] = (UINT16) LoopVar1; + mRight[LoopVar3] = (UINT16) LoopVar2; + } while (mHeapSize > 1); + + mSortPtr = CodeParm; + MakeLen (LoopVar3); + MakeCode (NParm, LenParm, CodeParm); + + // + // return root + // + return LoopVar3; +} + +/** + Outputs rightmost LoopVar8 bits of x + + @param[in] LoopVar8 The rightmost LoopVar8 bits of the data is used. + @param[in] x The data. +**/ +VOID +PutBits ( + IN INT32 LoopVar8, + IN UINT32 x + ) +{ + UINT8 Temp; + + if (LoopVar8 < mBitCount) { + mSubBitBuf |= x << (mBitCount -= LoopVar8); + } else { + + Temp = (UINT8)(mSubBitBuf | (x >> (LoopVar8 -= mBitCount))); + if (mDst < mDstUpperLimit) { + *mDst++ = Temp; + } + mCompSize++; + + if (LoopVar8 < UINT8_BIT) { + mSubBitBuf = x << (mBitCount = UINT8_BIT - LoopVar8); + } else { + + Temp = (UINT8)(x >> (LoopVar8 - UINT8_BIT)); + if (mDst < mDstUpperLimit) { + *mDst++ = Temp; + } + mCompSize++; + + mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - LoopVar8); + } + } +} + +/** + Encode a signed 32 bit number. + + @param[in] LoopVar5 The number to encode. +**/ +VOID +EncodeC ( + IN INT32 LoopVar5 + ) +{ + PutBits (mCLen[LoopVar5], mCCode[LoopVar5]); +} + +/** + Encode a unsigned 32 bit number. + + @param[in] LoopVar7 The number to encode. +**/ +VOID +EncodeP ( + IN UINT32 LoopVar7 + ) +{ + UINT32 LoopVar5; + + UINT32 LoopVar6; + + LoopVar5 = 0; + LoopVar6 = LoopVar7; + while (LoopVar6 != 0) { + LoopVar6 >>= 1; + LoopVar5++; + } + + PutBits (mPTLen[LoopVar5], mPTCode[LoopVar5]); + if (LoopVar5 > 1) { + PutBits(LoopVar5 - 1, LoopVar7 & (0xFFFFU >> (17 - LoopVar5))); + } +} + +/** + Count the frequencies for the Extra Set. + +**/ +VOID +CountTFreq ( + VOID + ) +{ + INT32 LoopVar1; + + INT32 LoopVar3; + + INT32 LoopVar8; + + INT32 Count; + + for (LoopVar1 = 0; LoopVar1 < NT; LoopVar1++) { + mTFreq[LoopVar1] = 0; + } + + LoopVar8 = NC; + while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) { + LoopVar8--; + } + + LoopVar1 = 0; + while (LoopVar1 < LoopVar8) { + LoopVar3 = mCLen[LoopVar1++]; + if (LoopVar3 == 0) { + Count = 1; + while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) { + LoopVar1++; + Count++; + } + + if (Count <= 2) { + mTFreq[0] = (UINT16) (mTFreq[0] + Count); + } else if (Count <= 18) { + mTFreq[1]++; + } else if (Count == 19) { + mTFreq[0]++; + mTFreq[1]++; + } else { + mTFreq[2]++; + } + } else { + ASSERT((LoopVar3+2)<(2 * NT - 1)); + mTFreq[LoopVar3 + 2]++; + } + } +} + +/** + Outputs the code length array for the Extra Set or the Position Set. + + @param[in] LoopVar8 The number of symbols. + @param[in] nbit The number of bits needed to represent 'LoopVar8'. + @param[in] Special The special symbol that needs to be take care of. + +**/ +VOID +WritePTLen ( + IN INT32 LoopVar8, + IN INT32 nbit, + IN INT32 Special + ) +{ + INT32 LoopVar1; + + INT32 LoopVar3; + + while (LoopVar8 > 0 && mPTLen[LoopVar8 - 1] == 0) { + LoopVar8--; + } + + PutBits (nbit, LoopVar8); + LoopVar1 = 0; + while (LoopVar1 < LoopVar8) { + LoopVar3 = mPTLen[LoopVar1++]; + if (LoopVar3 <= 6) { + PutBits (3, LoopVar3); + } else { + PutBits (LoopVar3 - 3, (1U << (LoopVar3 - 3)) - 2); + } + + if (LoopVar1 == Special) { + while (LoopVar1 < 6 && mPTLen[LoopVar1] == 0) { + LoopVar1++; + } + + PutBits (2, (LoopVar1 - 3) & 3); + } + } +} + +/** + Outputs the code length array for Char&Length Set. +**/ +VOID +WriteCLen ( + VOID + ) +{ + INT32 LoopVar1; + + INT32 LoopVar3; + + INT32 LoopVar8; + + INT32 Count; + + LoopVar8 = NC; + while (LoopVar8 > 0 && mCLen[LoopVar8 - 1] == 0) { + LoopVar8--; + } + + PutBits (CBIT, LoopVar8); + LoopVar1 = 0; + while (LoopVar1 < LoopVar8) { + LoopVar3 = mCLen[LoopVar1++]; + if (LoopVar3 == 0) { + Count = 1; + while (LoopVar1 < LoopVar8 && mCLen[LoopVar1] == 0) { + LoopVar1++; + Count++; + } + + if (Count <= 2) { + for (LoopVar3 = 0; LoopVar3 < Count; LoopVar3++) { + PutBits (mPTLen[0], mPTCode[0]); + } + } else if (Count <= 18) { + PutBits (mPTLen[1], mPTCode[1]); + PutBits (4, Count - 3); + } else if (Count == 19) { + PutBits (mPTLen[0], mPTCode[0]); + PutBits (mPTLen[1], mPTCode[1]); + PutBits (4, 15); + } else { + PutBits (mPTLen[2], mPTCode[2]); + PutBits (CBIT, Count - 20); + } + } else { + ASSERT((LoopVar3+2)<NPT); + PutBits (mPTLen[LoopVar3 + 2], mPTCode[LoopVar3 + 2]); + } + } +} + +/** + Huffman code the block and output it. + +**/ +VOID +SendBlock ( + VOID + ) +{ + UINT32 LoopVar1; + + UINT32 LoopVar3; + + UINT32 Flags; + + UINT32 Root; + + UINT32 Pos; + + UINT32 Size; + Flags = 0; + + Root = MakeTree (NC, mCFreq, mCLen, mCCode); + Size = mCFreq[Root]; + PutBits (16, Size); + if (Root >= NC) { + CountTFreq (); + Root = MakeTree (NT, mTFreq, mPTLen, mPTCode); + if (Root >= NT) { + WritePTLen (NT, TBIT, 3); + } else { + PutBits (TBIT, 0); + PutBits (TBIT, Root); + } + + WriteCLen (); + } else { + PutBits (TBIT, 0); + PutBits (TBIT, 0); + PutBits (CBIT, 0); + PutBits (CBIT, Root); + } + + Root = MakeTree (NP, mPFreq, mPTLen, mPTCode); + if (Root >= NP) { + WritePTLen (NP, PBIT, -1); + } else { + PutBits (PBIT, 0); + PutBits (PBIT, Root); + } + + Pos = 0; + for (LoopVar1 = 0; LoopVar1 < Size; LoopVar1++) { + if (LoopVar1 % UINT8_BIT == 0) { + Flags = mBuf[Pos++]; + } else { + Flags <<= 1; + } + if ((Flags & (1U << (UINT8_BIT - 1))) != 0){ + EncodeC(mBuf[Pos++] + (1U << UINT8_BIT)); + LoopVar3 = mBuf[Pos++] << UINT8_BIT; + LoopVar3 += mBuf[Pos++]; + + EncodeP (LoopVar3); + } else { + EncodeC (mBuf[Pos++]); + } + } + + SetMem (mCFreq, NC * sizeof (UINT16), 0); + SetMem (mPFreq, NP * sizeof (UINT16), 0); +} + +/** + Start the huffman encoding. + +**/ +VOID +HufEncodeStart ( + VOID + ) +{ + SetMem (mCFreq, NC * sizeof (UINT16), 0); + SetMem (mPFreq, NP * sizeof (UINT16), 0); + + mOutputPos = mOutputMask = 0; + + mBitCount = UINT8_BIT; + mSubBitBuf = 0; +} + +/** + Outputs an Original Character or a Pointer. + + @param[in] LoopVar5 The original character or the 'String Length' element of + a Pointer. + @param[in] LoopVar7 The 'Position' field of a Pointer. +**/ +VOID +CompressOutput ( + IN UINT32 LoopVar5, + IN UINT32 LoopVar7 + ) +{ + STATIC UINT32 CPos; + + if ((mOutputMask >>= 1) == 0) { + mOutputMask = 1U << (UINT8_BIT - 1); + if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) { + SendBlock (); + mOutputPos = 0; + } + + CPos = mOutputPos++; + mBuf[CPos] = 0; + } + mBuf[mOutputPos++] = (UINT8) LoopVar5; + mCFreq[LoopVar5]++; + if (LoopVar5 >= (1U << UINT8_BIT)) { + mBuf[CPos] = (UINT8)(mBuf[CPos]|mOutputMask); + mBuf[mOutputPos++] = (UINT8)(LoopVar7 >> UINT8_BIT); + mBuf[mOutputPos++] = (UINT8) LoopVar7; + LoopVar5 = 0; + while (LoopVar7!=0) { + LoopVar7 >>= 1; + LoopVar5++; + } + mPFreq[LoopVar5]++; + } +} + +/** + End the huffman encoding. + +**/ +VOID +HufEncodeEnd ( + VOID + ) +{ + SendBlock (); + + // + // Flush remaining bits + // + PutBits (UINT8_BIT - 1, 0); +} + +/** + The main controlling routine for compression process. + + @retval EFI_SUCCESS The compression is successful. + @retval EFI_OUT_0F_RESOURCES Not enough memory for compression process. +**/ +EFI_STATUS +Encode ( + VOID + ) +{ + EFI_STATUS Status; + INT32 LastMatchLen; + NODE LastMatchPos; + + Status = AllocateMemory (); + if (EFI_ERROR (Status)) { + FreeMemory (); + return Status; + } + + InitSlide (); + + HufEncodeStart (); + + mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH); + + mMatchLen = 0; + mPos = WNDSIZ; + InsertNode (); + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + + while (mRemainder > 0) { + LastMatchLen = mMatchLen; + LastMatchPos = mMatchPos; + if (!GetNextMatch ()) { + Status = EFI_OUT_OF_RESOURCES; + } + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + + if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) { + // + // Not enough benefits are gained by outputting a pointer, + // so just output the original character + // + CompressOutput(mText[mPos - 1], 0); + } else { + // + // Outputting a pointer is beneficial enough, do it. + // + + CompressOutput(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD), + (mPos - LastMatchPos - 2) & (WNDSIZ - 1)); + LastMatchLen--; + while (LastMatchLen > 0) { + if (!GetNextMatch ()) { + Status = EFI_OUT_OF_RESOURCES; + } + LastMatchLen--; + } + + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + } + } + + HufEncodeEnd (); + FreeMemory (); + return (Status); +} + +/** + The compression routine. + + @param[in] SrcBuffer The buffer containing the source data. + @param[in] SrcSize Number of bytes in SrcBuffer. + @param[in] DstBuffer The buffer to put the compressed image in. + @param[in, out] DstSize On input the size (in bytes) of DstBuffer, on + return the number of bytes placed in DstBuffer. + + @retval EFI_SUCCESS The compression was sucessful. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. DstSize is required. +**/ +EFI_STATUS +Compress ( + IN VOID *SrcBuffer, + IN UINT64 SrcSize, + IN VOID *DstBuffer, + IN OUT UINT64 *DstSize + ) +{ + EFI_STATUS Status; + + // + // Initializations + // + mBufSiz = 0; + mBuf = NULL; + mText = NULL; + mLevel = NULL; + mChildCount = NULL; + mPosition = NULL; + mParent = NULL; + mPrev = NULL; + mNext = NULL; + + mSrc = SrcBuffer; + mSrcUpperLimit = mSrc + SrcSize; + mDst = DstBuffer; + mDstUpperLimit = mDst +*DstSize; + + PutDword (0L); + PutDword (0L); + + MakeCrcTable (); + + mOrigSize = mCompSize = 0; + mCrc = INIT_CRC; + + // + // Compress it + // + Status = Encode (); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + // + // Null terminate the compressed data + // + if (mDst < mDstUpperLimit) { + *mDst++ = 0; + } + // + // Fill in compressed size and original size + // + mDst = DstBuffer; + PutDword (mCompSize + 1); + PutDword (mOrigSize); + + // + // Return + // + if (mCompSize + 1 + 8 > *DstSize) { + *DstSize = mCompSize + 1 + 8; + return EFI_BUFFER_TOO_SMALL; + } else { + *DstSize = mCompSize + 1 + 8; + return EFI_SUCCESS; + } + +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.h new file mode 100644 index 00000000..150c538e --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Compress.h @@ -0,0 +1,33 @@ +/** @file + Header file for compression routine. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_SHELL_COMPRESS_H_ +#define _EFI_SHELL_COMPRESS_H_ + +/** + The compression routine. + + @param[in] SrcBuffer The buffer containing the source data. + @param[in] SrcSize Number of bytes in SrcBuffer. + @param[in] DstBuffer The buffer to put the compressed image in. + @param[in, out] DstSize On input the size (in bytes) of DstBuffer, on + return the number of bytes placed in DstBuffer. + + @retval EFI_SUCCESS The compression was sucessful. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. DstSize is required. +**/ +EFI_STATUS +Compress ( + IN VOID *SrcBuffer, + IN UINT64 SrcSize, + IN VOID *DstBuffer, + IN OUT UINT64 *DstSize + ); + +#endif + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dblk.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dblk.c new file mode 100644 index 00000000..8fc876d0 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dblk.c @@ -0,0 +1,201 @@ +/** @file + Main file for Dblk shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Protocol/BlockIo.h> + +/** + Display blocks to the screen. + + @param[in] DevPath The device path to get the blocks from. + @param[in] Lba The Lba number to start from. + @param[in] BlockCount How many blocks to display. + + @retval SHELL_SUCCESS The display was successful. +**/ +SHELL_STATUS +DisplayTheBlocks( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath, + IN CONST UINT64 Lba, + IN CONST UINT8 BlockCount + ) +{ + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_HANDLE BlockIoHandle; + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + UINT8 *Buffer; + UINT8 *OriginalBuffer; + UINTN BufferSize; + + ShellStatus = SHELL_SUCCESS; + + Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, (EFI_DEVICE_PATH_PROTOCOL **)&DevPath, &BlockIoHandle); + if (EFI_ERROR(Status)) { + return (SHELL_NOT_FOUND); + } + + Status = gBS->OpenProtocol(BlockIoHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + return (SHELL_NOT_FOUND); + } + + BufferSize = BlockIo->Media->BlockSize * BlockCount; + if(BlockIo->Media->IoAlign == 0) { + BlockIo->Media->IoAlign = 1; + } + + if (BufferSize > 0) { + OriginalBuffer = AllocateZeroPool(BufferSize + BlockIo->Media->IoAlign); + Buffer = ALIGN_POINTER (OriginalBuffer,BlockIo->Media->IoAlign); + } else { + ShellPrintEx(-1,-1,L" BlockSize: 0x%08x, BlockCount: 0x%08x\r\n", BlockIo->Media->BlockSize, BlockCount); + OriginalBuffer = NULL; + Buffer = NULL; + } + + Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, Lba, BufferSize, Buffer); + if (!EFI_ERROR(Status) && Buffer != NULL) { + ShellPrintHiiEx( + -1, + -1, + NULL, + STRING_TOKEN (STR_DBLK_HEADER), + gShellDebug1HiiHandle, + Lba, + BufferSize, + BlockIo + ); + + DumpHex(2,0,BufferSize,Buffer); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDebug1HiiHandle, L"dblk", L"BlockIo"); + ShellStatus = SHELL_DEVICE_ERROR; + } + + if (OriginalBuffer != NULL) { + FreePool (OriginalBuffer); + } + + gBS->CloseProtocol(BlockIoHandle, &gEfiBlockIoProtocolGuid, gImageHandle, NULL); + return (ShellStatus); +} + +/** + Function for 'dblk' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDblk ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *BlockName; + CONST CHAR16 *LbaString; + CONST CHAR16 *BlockCountString; + UINT64 Lba; + UINT64 BlockCount; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dblk", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 4) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dblk"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) < 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"dblk"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // Parse the params + // + BlockName = ShellCommandLineGetRawValue(Package, 1); + LbaString = ShellCommandLineGetRawValue(Package, 2); + BlockCountString = ShellCommandLineGetRawValue(Package, 3); + + if (LbaString == NULL) { + Lba = 0; + } else { + if (!ShellIsHexOrDecimalNumber(LbaString, TRUE, FALSE)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dblk", LbaString); + ShellStatus = SHELL_INVALID_PARAMETER; + } + ShellConvertStringToUint64(LbaString, &Lba, TRUE, FALSE); + } + + if (BlockCountString == NULL) { + BlockCount = 1; + } else { + if (!ShellIsHexOrDecimalNumber(BlockCountString, TRUE, FALSE)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dblk", BlockCountString); + ShellStatus = SHELL_INVALID_PARAMETER; + } + ShellConvertStringToUint64(BlockCountString, &BlockCount, TRUE, FALSE); + if (BlockCount > 0x10) { + BlockCount = 0x10; + } else if (BlockCount == 0) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dblk", BlockCountString); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + + if (ShellStatus == SHELL_SUCCESS) { + // + // do the work if we have a valid block identifier + // + if (gEfiShellProtocol->GetDevicePathFromMap(BlockName) == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dblk", BlockName); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + DevPath = (EFI_DEVICE_PATH_PROTOCOL*)gEfiShellProtocol->GetDevicePathFromMap(BlockName); + if (gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &DevPath, NULL) == EFI_NOT_FOUND) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MAP_PROTOCOL), gShellDebug1HiiHandle, L"dblk", BlockName, L"BlockIo"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ShellStatus = DisplayTheBlocks(gEfiShellProtocol->GetDevicePathFromMap(BlockName), Lba, (UINT8)BlockCount); + } + } + } + } + + ShellCommandLineFreeVarList (Package); + } + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c new file mode 100644 index 00000000..ecba00b1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c @@ -0,0 +1,222 @@ +/** @file + Main file for Dmem shell Debug1 function. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Protocol/PciRootBridgeIo.h> +#include <Guid/Acpi.h> +#include <Guid/Mps.h> +#include <Guid/SmBios.h> + +/** + Make a printable character. + + If Char is printable then return it, otherwise return a question mark. + + @param[in] Char The character to make printable. + + @return A printable character representing Char. +**/ +CHAR16 +MakePrintable( + IN CONST CHAR16 Char + ) +{ + if ((Char < 0x20 && Char > 0)||(Char > 126)) { + return (L'?'); + } + return (Char); +} + +/** + Display some Memory-Mapped-IO memory. + + @param[in] Address The starting address to display. + @param[in] Size The length of memory to display. +**/ +SHELL_STATUS +DisplayMmioMemory( + IN CONST VOID *Address, + IN CONST UINTN Size + ) +{ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRbIo; + EFI_STATUS Status; + VOID *Buffer; + SHELL_STATUS ShellStatus; + + ShellStatus = SHELL_SUCCESS; + + Status = gBS->LocateProtocol(&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**)&PciRbIo); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"dmem"); + return (SHELL_NOT_FOUND); + } + Buffer = AllocateZeroPool(Size); + if (Buffer == NULL) { + return SHELL_OUT_OF_RESOURCES; + } + + Status = PciRbIo->Mem.Read(PciRbIo, EfiPciWidthUint8, (UINT64)(UINTN)Address, Size, Buffer); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_ER), gShellDebug1HiiHandle, L"dmem"); + ShellStatus = SHELL_NOT_FOUND; + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_MMIO_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size); + DumpHex(2, (UINTN)Address, Size, Buffer); + } + + FreePool(Buffer); + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-mmio", TypeFlag}, + {NULL, TypeMax} + }; + +/** + Function for 'dmem' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDmem ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + VOID *Address; + UINT64 Size; + CONST CHAR16 *Temp1; + UINT64 AcpiTableAddress; + UINT64 Acpi20TableAddress; + UINT64 SalTableAddress; + UINT64 SmbiosTableAddress; + UINT64 MpsTableAddress; + UINTN TableWalker; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + Address = NULL; + Size = 0; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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), gShellDebug1HiiHandle, L"dmem", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmem"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Temp1 = ShellCommandLineGetRawValue(Package, 1); + if (Temp1 == NULL) { + Address = gST; + Size = sizeof (*gST); + } else { + if (!ShellIsHexOrDecimalNumber(Temp1, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp1, (UINT64*)&Address, TRUE, FALSE))) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmem", Temp1); + ShellStatus = SHELL_INVALID_PARAMETER; + } + Temp1 = ShellCommandLineGetRawValue(Package, 2); + if (Temp1 == NULL) { + Size = 512; + } else { + if (!ShellIsHexOrDecimalNumber(Temp1, FALSE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp1, &Size, TRUE, FALSE))) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmem", Temp1); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } + } + + if (ShellStatus == SHELL_SUCCESS) { + if (!ShellCommandLineGetFlag(Package, L"-mmio")) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size); + DumpHex(2, (UINTN)Address, (UINTN)Size, Address); + if (Address == (VOID*)gST) { + Acpi20TableAddress = 0; + AcpiTableAddress = 0; + SalTableAddress = 0; + SmbiosTableAddress = 0; + MpsTableAddress = 0; + for (TableWalker = 0 ; TableWalker < gST->NumberOfTableEntries ; TableWalker++) { + if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiAcpi20TableGuid)) { + Acpi20TableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } + if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiAcpi10TableGuid)) { + AcpiTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } + if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiSmbiosTableGuid)) { + SmbiosTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } + if (CompareGuid (&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiSmbios3TableGuid)) { + SmbiosTableAddress = (UINT64) (UINTN) gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } + if (CompareGuid(&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiMpsTableGuid)) { + MpsTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable; + continue; + } + } + + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_SYSTEM_TABLE), gShellDebug1HiiHandle, + (UINT64)(UINTN)Address, + gST->Hdr.HeaderSize, + gST->Hdr.Revision, + (UINT64)(UINTN)gST->ConIn, + (UINT64)(UINTN)gST->ConOut, + (UINT64)(UINTN)gST->StdErr, + (UINT64)(UINTN)gST->RuntimeServices, + (UINT64)(UINTN)gST->BootServices, + SalTableAddress, + AcpiTableAddress, + Acpi20TableAddress, + MpsTableAddress, + SmbiosTableAddress + ); + } + } else { + ShellStatus = DisplayMmioMemory(Address, (UINTN)Size); + } + } + + + ShellCommandLineFreeVarList (Package); + } + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c new file mode 100644 index 00000000..d96c71e4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c @@ -0,0 +1,859 @@ +/** @file + Main file for DmpStore shell Debug1 function. + + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" + +typedef enum { + DmpStoreDisplay, + DmpStoreDelete, + DmpStoreSave, + DmpStoreLoad +} DMP_STORE_TYPE; + +typedef struct { + UINT32 Signature; + CHAR16 *Name; + EFI_GUID Guid; + UINT32 Attributes; + UINT32 DataSize; + UINT8 *Data; + LIST_ENTRY Link; +} DMP_STORE_VARIABLE; + +#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's') + +/** + Base on the input attribute value to return the attribute string. + + @param[in] Atts The input attribute value + + @retval The attribute string info. +**/ +CHAR16 * +GetAttrType ( + IN CONST UINT32 Atts + ) +{ + UINTN BufLen; + CHAR16 *RetString; + + BufLen = 0; + RetString = NULL; + + if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+NV", 0); + } + if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+RT+BS", 0); + } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+BS", 0); + } + if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+HR", 0); + } + if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+AW", 0); + } + if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { + StrnCatGrow (&RetString, &BufLen, L"+AT", 0); + } + + if (RetString == NULL) { + RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0); + } + + if ((RetString != NULL) && (RetString[0] == L'+')) { + CopyMem(RetString, RetString + 1, StrSize(RetString + 1)); + } + + return RetString; +} + +/** + Convert binary to hex format string. + + @param[in] Buffer The binary data. + @param[in] BufferSize The size in bytes of the binary data. + @param[in, out] HexString Hex format string. + @param[in] HexStringSize The size in bytes of the string. + + @return The hex format string. +**/ +CHAR16* +BinaryToHexString ( + IN VOID *Buffer, + IN UINTN BufferSize, + IN OUT CHAR16 *HexString, + IN UINTN HexStringSize + ) +{ + UINTN Index; + UINTN StringIndex; + + ASSERT (Buffer != NULL); + ASSERT ((BufferSize * 2 + 1) * sizeof (CHAR16) <= HexStringSize); + + for (Index = 0, StringIndex = 0; Index < BufferSize; Index += 1) { + StringIndex += + UnicodeSPrint ( + &HexString[StringIndex], + HexStringSize - StringIndex * sizeof (CHAR16), + L"%02x", + ((UINT8 *) Buffer)[Index] + ); + } + return HexString; +} + +/** + Load the variable data from file and set to variable data base. + + @param[in] FileHandle The file to be read. + @param[in] Name The name of the variables to be loaded. + @param[in] Guid The guid of the variables to be loaded. + @param[out] Found TRUE when at least one variable was loaded and set. + + @retval SHELL_DEVICE_ERROR Cannot access the file. + @retval SHELL_VOLUME_CORRUPTED The file is in bad format. + @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation. + @retval SHELL_SUCCESS Successfully load and set the variables. +**/ +SHELL_STATUS +LoadVariablesFromFile ( + IN SHELL_FILE_HANDLE FileHandle, + IN CONST CHAR16 *Name, + IN CONST EFI_GUID *Guid, + OUT BOOLEAN *Found + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + UINT32 NameSize; + UINT32 DataSize; + UINTN BufferSize; + UINTN RemainingSize; + UINT64 Position; + UINT64 FileSize; + LIST_ENTRY List; + DMP_STORE_VARIABLE *Variable; + LIST_ENTRY *Link; + CHAR16 *Attributes; + UINT8 *Buffer; + UINT32 Crc32; + + Status = ShellGetFileSize (FileHandle, &FileSize); + if (EFI_ERROR (Status)) { + return SHELL_DEVICE_ERROR; + } + + ShellStatus = SHELL_SUCCESS; + + InitializeListHead (&List); + + Position = 0; + while (Position < FileSize) { + // + // NameSize + // + BufferSize = sizeof (NameSize); + Status = ShellReadFile (FileHandle, &BufferSize, &NameSize); + if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) { + ShellStatus = SHELL_VOLUME_CORRUPTED; + break; + } + + // + // DataSize + // + BufferSize = sizeof (DataSize); + Status = ShellReadFile (FileHandle, &BufferSize, &DataSize); + if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) { + ShellStatus = SHELL_VOLUME_CORRUPTED; + break; + } + + // + // Name, Guid, Attributes, Data, Crc32 + // + RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32); + BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize; + Buffer = AllocatePool (BufferSize); + if (Buffer == NULL) { + ShellStatus = SHELL_OUT_OF_RESOURCES; + break; + } + BufferSize = RemainingSize; + Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2); + if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) { + ShellStatus = SHELL_VOLUME_CORRUPTED; + FreePool (Buffer); + break; + } + + // + // Check Crc32 + // + * (UINT32 *) Buffer = NameSize; + * ((UINT32 *) Buffer + 1) = DataSize; + BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32); + gBS->CalculateCrc32 ( + Buffer, + BufferSize, + &Crc32 + ); + if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) { + FreePool (Buffer); + ShellStatus = SHELL_VOLUME_CORRUPTED; + break; + } + + Position += BufferSize + sizeof (Crc32); + + Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize); + if (Variable == NULL) { + FreePool (Buffer); + ShellStatus = SHELL_OUT_OF_RESOURCES; + break; + } + Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE; + Variable->Name = (CHAR16 *) (Variable + 1); + Variable->DataSize = DataSize; + Variable->Data = (UINT8 *) Variable->Name + NameSize; + CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize); + CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID)); + CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32)); + CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize); + + InsertTailList (&List, &Variable->Link); + FreePool (Buffer); + } + + if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle, L"dmpstore"); + if (Position != FileSize) { + ShellStatus = SHELL_VOLUME_CORRUPTED; + } + } + + for ( Link = GetFirstNode (&List) + ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS) + ; Link = GetNextNode (&List, Link) + ) { + Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE); + + if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) && + ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid)) + ) { + Attributes = GetAttrType (Variable->Attributes); + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle, + Attributes, &Variable->Guid, Variable->Name, Variable->DataSize + ); + SHELL_FREE_NON_NULL(Attributes); + + *Found = TRUE; + Status = gRT->SetVariable ( + Variable->Name, + &Variable->Guid, + Variable->Attributes, + Variable->DataSize, + Variable->Data + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", Variable->Name, Status); + } + } + } + + for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) { + Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE); + Link = RemoveEntryList (&Variable->Link); + FreePool (Variable); + } + + return ShellStatus; +} + +/** + Append one variable to file. + + @param[in] FileHandle The file to be appended. + @param[in] Name The variable name. + @param[in] Guid The variable GUID. + @param[in] Attributes The variable attributes. + @param[in] DataSize The variable data size. + @param[in] Data The variable data. + + @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation. + @retval EFI_SUCCESS The variable is appended to file successfully. + @retval others Failed to append the variable to file. +**/ +EFI_STATUS +AppendSingleVariableToFile ( + IN SHELL_FILE_HANDLE FileHandle, + IN CONST CHAR16 *Name, + IN CONST EFI_GUID *Guid, + IN UINT32 Attributes, + IN UINT32 DataSize, + IN CONST UINT8 *Data + ) +{ + UINT32 NameSize; + UINT8 *Buffer; + UINT8 *Ptr; + UINTN BufferSize; + EFI_STATUS Status; + + NameSize = (UINT32) StrSize (Name); + BufferSize = sizeof (NameSize) + sizeof (DataSize) + + sizeof (*Guid) + + sizeof (Attributes) + + NameSize + DataSize + + sizeof (UINT32); + + Buffer = AllocatePool (BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr = Buffer; + // + // NameSize and DataSize + // + * (UINT32 *) Ptr = NameSize; + Ptr += sizeof (NameSize); + *(UINT32 *) Ptr = DataSize; + Ptr += sizeof (DataSize); + + // + // Name + // + CopyMem (Ptr, Name, NameSize); + Ptr += NameSize; + + // + // Guid + // + CopyMem (Ptr, Guid, sizeof (*Guid)); + Ptr += sizeof (*Guid); + + // + // Attributes + // + * (UINT32 *) Ptr = Attributes; + Ptr += sizeof (Attributes); + + // + // Data + // + CopyMem (Ptr, Data, DataSize); + Ptr += DataSize; + + // + // Crc32 + // + gBS->CalculateCrc32 (Buffer, (UINTN) Ptr - (UINTN) Buffer, (UINT32 *) Ptr); + + Status = ShellWriteFile (FileHandle, &BufferSize, Buffer); + FreePool (Buffer); + + if (!EFI_ERROR (Status) && + (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32)) + ) { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Recursive function to display or delete variables. + + This function will call itself to create a stack-based list of allt he variables to process, + then fromt he last to the first, they will do either printing or deleting. + + This is necessary since once a delete happens GetNextVariableName() will work. + + @param[in] Name The variable name of the EFI variable (or NULL). + @param[in] Guid The GUID of the variable set (or NULL). + @param[in] Type The operation type. + @param[in] FileHandle The file to operate on (or NULL). + @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start. + @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start. + @param[in] FoundOne If a VariableName or Guid was specified and one was printed or + deleted, then set this to TRUE, otherwise ignored. + @param[in] StandardFormatOutput TRUE indicates Standard-Format Output. + + @retval SHELL_SUCCESS The operation was successful. + @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed. + @retval SHELL_ABORTED The abort message was received. + @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error. + @retval SHELL_NOT_FOUND the Name/Guid pair could not be found. +**/ +SHELL_STATUS +CascadeProcessVariables ( + IN CONST CHAR16 *Name OPTIONAL, + IN CONST EFI_GUID *Guid OPTIONAL, + IN DMP_STORE_TYPE Type, + IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL, + IN CONST CHAR16 * CONST PrevName, + IN EFI_GUID FoundVarGuid, + IN BOOLEAN *FoundOne, + IN BOOLEAN StandardFormatOutput + ) +{ + EFI_STATUS Status; + CHAR16 *FoundVarName; + UINT8 *DataBuffer; + UINTN DataSize; + UINT32 Atts; + SHELL_STATUS ShellStatus; + UINTN NameSize; + CHAR16 *AttrString; + CHAR16 *HexString; + EFI_STATUS SetStatus; + CONST CHAR16 *GuidName; + + if (ShellGetExecutionBreakFlag()) { + return (SHELL_ABORTED); + } + + NameSize = 0; + FoundVarName = NULL; + + if (PrevName!=NULL) { + StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0); + } else { + FoundVarName = AllocateZeroPool(sizeof(CHAR16)); + NameSize = sizeof(CHAR16); + } + + Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid); + if (Status == EFI_BUFFER_TOO_SMALL) { + SHELL_FREE_NON_NULL(FoundVarName); + FoundVarName = AllocateZeroPool (NameSize); + if (FoundVarName != NULL) { + if (PrevName != NULL) { + StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1); + } + + Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid); + } else { + Status = EFI_OUT_OF_RESOURCES; + } + } + + // + // No more is fine. + // + if (Status == EFI_NOT_FOUND) { + SHELL_FREE_NON_NULL(FoundVarName); + return (SHELL_SUCCESS); + } else if (EFI_ERROR(Status)) { + SHELL_FREE_NON_NULL(FoundVarName); + return (SHELL_DEVICE_ERROR); + } + + // + // Recurse to the next iteration. We know "our" variable's name. + // + ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne, StandardFormatOutput); + + if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) { + SHELL_FREE_NON_NULL(FoundVarName); + return (SHELL_ABORTED); + } + + // + // No matter what happened we process our own variable + // Only continue if Guid and VariableName are each either NULL or a match + // + if ( ( Name == NULL + || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) ) + && ( Guid == NULL + || CompareGuid(&FoundVarGuid, Guid) ) + ) { + DataSize = 0; + DataBuffer = NULL; + // + // do the print or delete + // + *FoundOne = TRUE; + Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + SHELL_FREE_NON_NULL (DataBuffer); + DataBuffer = AllocatePool (DataSize); + if (DataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer); + } + } + // + // Last error check then print this variable out. + // + if (Type == DmpStoreDisplay) { + if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) { + AttrString = GetAttrType(Atts); + if (StandardFormatOutput) { + HexString = AllocatePool ((DataSize * 2 + 1) * sizeof (CHAR16)); + if (HexString != NULL) { + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_VAR_SFO), gShellDebug1HiiHandle, + FoundVarName, &FoundVarGuid, Atts, DataSize, + BinaryToHexString ( + DataBuffer, DataSize, HexString, (DataSize * 2 + 1) * sizeof (CHAR16) + ) + ); + FreePool (HexString); + } else { + Status = EFI_OUT_OF_RESOURCES; + } + } else { + Status = gEfiShellProtocol->GetGuidName(&FoundVarGuid, &GuidName); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle, + AttrString, &FoundVarGuid, FoundVarName, DataSize + ); + } else { + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE2), gShellDebug1HiiHandle, + AttrString, GuidName, FoundVarName, DataSize + ); + } + DumpHex (2, 0, DataSize, DataBuffer); + } + SHELL_FREE_NON_NULL (AttrString); + } + } else if (Type == DmpStoreSave) { + if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) { + AttrString = GetAttrType (Atts); + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle, + AttrString, &FoundVarGuid, FoundVarName, DataSize + ); + Status = AppendSingleVariableToFile ( + FileHandle, + FoundVarName, + &FoundVarGuid, + Atts, + (UINT32) DataSize, + DataBuffer + ); + SHELL_FREE_NON_NULL (AttrString); + } + } else if (Type == DmpStoreDelete) { + // + // We only need name to delete it... + // + SetStatus = gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL); + if (StandardFormatOutput) { + if (SetStatus == EFI_SUCCESS) { + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_NG_SFO), gShellDebug1HiiHandle, + FoundVarName, &FoundVarGuid + ); + } + } else { + ShellPrintHiiEx ( + -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_DELETE_LINE), gShellDebug1HiiHandle, + &FoundVarGuid, FoundVarName, SetStatus + ); + } + } + SHELL_FREE_NON_NULL(DataBuffer); + } + + SHELL_FREE_NON_NULL(FoundVarName); + + if (Status == EFI_DEVICE_ERROR) { + ShellStatus = SHELL_DEVICE_ERROR; + } else if (Status == EFI_SECURITY_VIOLATION) { + ShellStatus = SHELL_SECURITY_VIOLATION; + } else if (EFI_ERROR(Status)) { + ShellStatus = SHELL_NOT_READY; + } + + return (ShellStatus); +} + +/** + Function to display or delete variables. This will set up and call into the recursive function. + + @param[in] Name The variable name of the EFI variable (or NULL). + @param[in] Guid The GUID of the variable set (or NULL). + @param[in] Type The operation type. + @param[in] FileHandle The file to save or load variables. + @param[in] StandardFormatOutput TRUE indicates Standard-Format Output. + + @retval SHELL_SUCCESS The operation was successful. + @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed. + @retval SHELL_ABORTED The abort message was received. + @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error. + @retval SHELL_NOT_FOUND the Name/Guid pair could not be found. +**/ +SHELL_STATUS +ProcessVariables ( + IN CONST CHAR16 *Name OPTIONAL, + IN CONST EFI_GUID *Guid OPTIONAL, + IN DMP_STORE_TYPE Type, + IN SHELL_FILE_HANDLE FileHandle OPTIONAL, + IN BOOLEAN StandardFormatOutput + ) +{ + SHELL_STATUS ShellStatus; + BOOLEAN Found; + EFI_GUID FoundVarGuid; + + Found = FALSE; + ShellStatus = SHELL_SUCCESS; + ZeroMem (&FoundVarGuid, sizeof(EFI_GUID)); + + if (StandardFormatOutput) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"dmpstore"); + } + + if (Type == DmpStoreLoad) { + ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found); + } else { + ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found, StandardFormatOutput); + } + + if (!Found) { + if (ShellStatus == SHELL_OUT_OF_RESOURCES) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore"); + return (ShellStatus); + } else if (Name != NULL && Guid == NULL) { + if (StandardFormatOutput) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N_SFO), gShellDebug1HiiHandle, Name); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, L"dmpstore", Name); + } + } else if (Name != NULL && Guid != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name); + } else if (Name == NULL && Guid == NULL) { + if (StandardFormatOutput) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_SFO), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle, L"dmpstore"); + } + } else if (Name == NULL && Guid != NULL) { + if (StandardFormatOutput) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G_SFO), gShellDebug1HiiHandle, Guid); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, L"dmpstore", Guid); + } + } + return (SHELL_NOT_FOUND); + } + return (ShellStatus); +} + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-d", TypeFlag}, + {L"-l", TypeValue}, + {L"-s", TypeValue}, + {L"-all", TypeFlag}, + {L"-guid", TypeValue}, + {L"-sfo", TypeFlag}, + {NULL, TypeMax} + }; + +/** + Function for 'dmpstore' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDmpStore ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + RETURN_STATUS RStatus; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *GuidStr; + CONST CHAR16 *File; + EFI_GUID *Guid; + EFI_GUID GuidData; + CONST CHAR16 *Name; + DMP_STORE_TYPE Type; + SHELL_FILE_HANDLE FileHandle; + EFI_FILE_INFO *FileInfo; + BOOLEAN StandardFormatOutput; + + ShellStatus = SHELL_SUCCESS; + Package = NULL; + FileHandle = NULL; + File = NULL; + Type = DmpStoreDisplay; + StandardFormatOutput = FALSE; + + 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), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-sfo")) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-sfo"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + // + // Determine the GUID to search for based on -all and -guid parameters + // + if (!ShellCommandLineGetFlag(Package, L"-all")) { + GuidStr = ShellCommandLineGetValue(Package, L"-guid"); + if (GuidStr != NULL) { + RStatus = StrToGuid (GuidStr, &GuidData); + if (RETURN_ERROR (RStatus) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); + ShellStatus = SHELL_INVALID_PARAMETER; + } + Guid = &GuidData; + } else { + Guid = &gEfiGlobalVariableGuid; + } + } else { + Guid = NULL; + } + + // + // Get the Name of the variable to find + // + Name = ShellCommandLineGetRawValue(Package, 1); + + if (ShellStatus == SHELL_SUCCESS) { + if (ShellCommandLineGetFlag(Package, L"-s")) { + Type = DmpStoreSave; + File = ShellCommandLineGetValue(Package, L"-s"); + if (File == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0); + if (!EFI_ERROR (Status)) { + // + // Delete existing file, but do not delete existing directory + // + FileInfo = ShellGetFileInfo (FileHandle); + if (FileInfo == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); + Status = EFI_DEVICE_ERROR; + } else { + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); + Status = EFI_INVALID_PARAMETER; + } else { + Status = ShellDeleteFile (&FileHandle); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); + } + } + FreePool (FileInfo); + } + } else if (Status == EFI_NOT_FOUND) { + // + // Good when file doesn't exist + // + Status = EFI_SUCCESS; + } else { + // + // Otherwise it's bad. + // + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); + } + + if (!EFI_ERROR (Status)) { + Status = ShellOpenFileByName (File, &FileHandle, 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), gShellDebug1HiiHandle, L"dmpstore", File); + } + } + + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + } else if (ShellCommandLineGetFlag(Package, L"-l")) { + Type = DmpStoreLoad; + File = ShellCommandLineGetValue(Package, L"-l"); + if (File == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + FileInfo = ShellGetFileInfo (FileHandle); + if (FileInfo == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); + ShellStatus = SHELL_DEVICE_ERROR; + } else { + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); + ShellStatus = SHELL_INVALID_PARAMETER; + } + FreePool (FileInfo); + } + } + } + } else if (ShellCommandLineGetFlag(Package, L"-d")) { + Type = DmpStoreDelete; + } + + if (ShellCommandLineGetFlag (Package,L"-sfo")) { + StandardFormatOutput = TRUE; + } + } + + if (ShellStatus == SHELL_SUCCESS) { + if (Type == DmpStoreSave) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File); + } else if (Type == DmpStoreLoad) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File); + } + ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput); + if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) { + ShellCloseFile (&FileHandle); + } + } + } + } + + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + return ShellStatus; +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Edit.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Edit.c new file mode 100644 index 00000000..02a3097d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Edit.c @@ -0,0 +1,156 @@ +/** @file + Main file for Edit shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "TextEditor.h" + +/** + Function for 'edit' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEdit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CHAR16 *Buffer; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + LIST_ENTRY *Package; + CONST CHAR16 *Cwd; + CHAR16 *Nfs; + CHAR16 *Spot; + CONST CHAR16 *TempParam; +// SHELL_FILE_HANDLE TempHandle; + + Buffer = NULL; + ShellStatus = SHELL_SUCCESS; + Nfs = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"edit", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"edit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Cwd = gEfiShellProtocol->GetCurDir(NULL); + if (Cwd == NULL) { + Cwd = ShellGetEnvironmentVariable(L"path"); + if (Cwd != NULL) { + Nfs = StrnCatGrow(&Nfs, NULL, Cwd+3, 0); + if (Nfs != NULL) { + Spot = StrStr(Nfs, L";"); + if (Spot != NULL) { + *Spot = CHAR_NULL; + } + Spot = StrStr(Nfs, L"\\"); + if (Spot != NULL) { + Spot[1] = CHAR_NULL; + } + gEfiShellProtocol->SetCurDir(NULL, Nfs); + FreePool(Nfs); + } + } + } + + Status = MainEditorInit (); + + if (EFI_ERROR (Status)) { + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_INIT_FAILED), gShellDebug1HiiHandle); + } else { + MainEditorBackup (); + + // + // if editor launched with file named + // + if (ShellCommandLineGetCount(Package) == 2) { + TempParam = ShellCommandLineGetRawValue(Package, 1); + ASSERT(TempParam != NULL); + FileBufferSetFileName (TempParam); +// if (EFI_ERROR(ShellFileExists(MainEditor.FileBuffer->FileName))) { +// Status = ShellOpenFileByName(MainEditor.FileBuffer->FileName, &TempHandle, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); +// if (!EFI_ERROR(Status)) { +// ShellCloseFile(&TempHandle); +// } +// } + } + + Status = FileBufferRead (MainEditor.FileBuffer->FileName, FALSE); + if (!EFI_ERROR (Status)) { + MainEditorRefresh (); + + Status = MainEditorKeyInput (); + } + + if (Status != EFI_OUT_OF_RESOURCES) { + // + // back up the status string + // + Buffer = CatSPrint (NULL, L"%s", StatusBarGetString()); + } + + MainEditorCleanup (); + + // + // print editor exit code on screen + // + if (Status == EFI_SUCCESS) { + } else if (Status == EFI_OUT_OF_RESOURCES) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"edit"); + } else { + if (Buffer != NULL) { + if (StrCmp (Buffer, L"") != 0) { + // + // print out the status string + // + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_BUFFER), gShellDebug1HiiHandle, Buffer); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle); + } + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle); + } + } + + if (Status != EFI_OUT_OF_RESOURCES) { + SHELL_FREE_NON_NULL (Buffer); + } + } + } + ShellCommandLineFreeVarList (Package); + } + return ShellStatus; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.c new file mode 100644 index 00000000..3c3f00fb --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.c @@ -0,0 +1,3321 @@ +/** @file + Implements filebuffer interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "TextEditor.h" +#include <Guid/FileSystemInfo.h> +#include <Library/FileHandleLib.h> + +EFI_EDITOR_FILE_BUFFER FileBuffer; +EFI_EDITOR_FILE_BUFFER FileBufferBackupVar; + +// +// for basic initialization of FileBuffer +// +EFI_EDITOR_FILE_BUFFER FileBufferConst = { + NULL, + FileTypeUnicode, + NULL, + NULL, + 0, + { + 0, + 0 + }, + { + 0, + 0 + }, + { + 0, + 0 + }, + { + 0, + 0 + }, + FALSE, + TRUE, + FALSE, + NULL +}; + +// +// the whole edit area needs to be refreshed +// +BOOLEAN FileBufferNeedRefresh; + +// +// only the current line in edit area needs to be refresh +// +BOOLEAN FileBufferOnlyLineNeedRefresh; + +BOOLEAN FileBufferMouseNeedRefresh; + +extern BOOLEAN EditorMouseAction; + +/** + Initialization function for FileBuffer. + + @param EFI_SUCCESS The initialization was successful. + @param EFI_LOAD_ERROR A default name could not be created. + @param EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferInit ( + VOID + ) +{ + // + // basically initialize the FileBuffer + // + CopyMem (&FileBuffer , &FileBufferConst, sizeof (EFI_EDITOR_FILE_BUFFER)); + CopyMem (&FileBufferBackupVar, &FileBufferConst, sizeof (EFI_EDITOR_FILE_BUFFER)); + + // + // set default FileName + // + FileBuffer.FileName = EditGetDefaultFileName (L"txt"); + if (FileBuffer.FileName == NULL) { + return EFI_LOAD_ERROR; + } + + FileBuffer.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY)); + if (FileBuffer.ListHead == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (FileBuffer.ListHead); + + FileBuffer.DisplayPosition.Row = 2; + FileBuffer.DisplayPosition.Column = 1; + FileBuffer.LowVisibleRange.Row = 2; + FileBuffer.LowVisibleRange.Column = 1; + + FileBufferNeedRefresh = FALSE; + FileBufferMouseNeedRefresh = FALSE; + FileBufferOnlyLineNeedRefresh = FALSE; + + return EFI_SUCCESS; +} + +/** + Backup function for FileBuffer. Only backup the following items: + Mouse/Cursor position + File Name, Type, ReadOnly, Modified + Insert Mode + + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The backup operation was successful. +**/ +EFI_STATUS +FileBufferBackup ( + VOID + ) +{ + FileBufferBackupVar.MousePosition = FileBuffer.MousePosition; + + SHELL_FREE_NON_NULL (FileBufferBackupVar.FileName); + FileBufferBackupVar.FileName = NULL; + FileBufferBackupVar.FileName = StrnCatGrow (&FileBufferBackupVar.FileName, NULL, FileBuffer.FileName, 0); + + FileBufferBackupVar.ModeInsert = FileBuffer.ModeInsert; + FileBufferBackupVar.FileType = FileBuffer.FileType; + + FileBufferBackupVar.FilePosition = FileBuffer.FilePosition; + FileBufferBackupVar.LowVisibleRange = FileBuffer.LowVisibleRange; + + FileBufferBackupVar.FileModified = FileBuffer.FileModified; + FileBufferBackupVar.ReadOnly = FileBuffer.ReadOnly; + + return EFI_SUCCESS; +} + +/** + Advance to the next Count lines + + @param[in] Count The line number to advance by. + @param[in] CurrentLine The pointer to the current line structure. + @param[in] LineList The pointer to the linked list of lines. + + @retval NULL There was an error. + @return The line structure after the advance. +**/ +EFI_EDITOR_LINE * +InternalEditorMiscLineAdvance ( + IN CONST UINTN Count, + IN CONST EFI_EDITOR_LINE *CurrentLine, + IN CONST LIST_ENTRY *LineList + ) + +{ + UINTN Index; + CONST EFI_EDITOR_LINE *Line; + + if (CurrentLine == NULL || LineList == NULL) { + return NULL; + } + + for (Line = CurrentLine, Index = 0; Index < Count; Index++) { + // + // if already last line + // + if (Line->Link.ForwardLink == LineList) { + return NULL; + } + + Line = CR (Line->Link.ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + } + + return ((EFI_EDITOR_LINE *)Line); +} + +/** + Retreat to the previous Count lines. + + @param[in] Count The line number to retreat by. + @param[in] CurrentLine The pointer to the current line structure. + @param[in] LineList The pointer to the linked list of lines. + + @retval NULL There was an error. + @return The line structure after the retreat. +**/ +EFI_EDITOR_LINE * +InternalEditorMiscLineRetreat ( + IN CONST UINTN Count, + IN CONST EFI_EDITOR_LINE *CurrentLine, + IN CONST LIST_ENTRY *LineList + ) + +{ + UINTN Index; + CONST EFI_EDITOR_LINE *Line; + + if (CurrentLine == NULL || LineList == NULL) { + return NULL; + } + + for (Line = CurrentLine, Index = 0; Index < Count; Index++) { + // + // already the first line + // + if (Line->Link.BackLink == LineList) { + return NULL; + } + + Line = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + } + + return ((EFI_EDITOR_LINE *)Line); +} + +/** + Advance/Retreat lines + + @param[in] Count line number to advance/retreat + >0 : advance + <0 : retreat + + @retval NULL An error occurred. + @return The line after advance/retreat. +**/ +EFI_EDITOR_LINE * +MoveLine ( + IN CONST INTN Count + ) +{ + EFI_EDITOR_LINE *Line; + UINTN AbsCount; + + // + // if < 0, then retreat + // if > 0, the advance + // + if (Count <= 0) { + AbsCount = (UINTN)ABS(Count); + Line = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead); + } else { + Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead); + } + + return Line; +} + +/** + Function to update the 'screen' to display the mouse position. + + @retval EFI_SUCCESS The backup operation was successful. +**/ +EFI_STATUS +FileBufferRestoreMousePosition ( + VOID + ) +{ + EFI_EDITOR_COLOR_UNION Orig; + EFI_EDITOR_COLOR_UNION New; + UINTN FRow; + UINTN FColumn; + BOOLEAN HasCharacter; + EFI_EDITOR_LINE *CurrentLine; + EFI_EDITOR_LINE *Line; + CHAR16 Value; + + // + // variable initialization + // + Line = NULL; + + if (MainEditor.MouseSupported) { + + if (FileBufferMouseNeedRefresh) { + + FileBufferMouseNeedRefresh = FALSE; + + // + // if mouse position not moved and only mouse action + // so do not need to refresh mouse position + // + if ((FileBuffer.MousePosition.Row == FileBufferBackupVar.MousePosition.Row && + FileBuffer.MousePosition.Column == FileBufferBackupVar.MousePosition.Column) + && EditorMouseAction) { + return EFI_SUCCESS; + } + // + // backup the old screen attributes + // + Orig = MainEditor.ColorAttributes; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + // + // clear the old mouse position + // + FRow = FileBuffer.LowVisibleRange.Row + FileBufferBackupVar.MousePosition.Row - 2; + + FColumn = FileBuffer.LowVisibleRange.Column + FileBufferBackupVar.MousePosition.Column - 1; + + HasCharacter = TRUE; + if (FRow > FileBuffer.NumLines) { + HasCharacter = FALSE; + } else { + CurrentLine = FileBuffer.CurrentLine; + Line = MoveLine (FRow - FileBuffer.FilePosition.Row); + + if (Line == NULL || FColumn > Line->Size) { + HasCharacter = FALSE; + } + + FileBuffer.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)FileBufferBackupVar.MousePosition.Column - 1, + (INT32)FileBufferBackupVar.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + Value = (Line->Buffer[FColumn - 1]); + ShellPrintEx ( + (INT32)FileBufferBackupVar.MousePosition.Column - 1, + (INT32)FileBufferBackupVar.MousePosition.Row - 1, + L"%c", + Value + ); + } + // + // set the new mouse position + // + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + + // + // clear the old mouse position + // + FRow = FileBuffer.LowVisibleRange.Row + FileBuffer.MousePosition.Row - 2; + FColumn = FileBuffer.LowVisibleRange.Column + FileBuffer.MousePosition.Column - 1; + + HasCharacter = TRUE; + if (FRow > FileBuffer.NumLines) { + HasCharacter = FALSE; + } else { + CurrentLine = FileBuffer.CurrentLine; + Line = MoveLine (FRow - FileBuffer.FilePosition.Row); + + if (Line == NULL || FColumn > Line->Size) { + HasCharacter = FALSE; + } + + FileBuffer.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)FileBuffer.MousePosition.Column - 1, + (INT32)FileBuffer.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + Value = Line->Buffer[FColumn - 1]; + ShellPrintEx ( + (INT32)FileBuffer.MousePosition.Column - 1, + (INT32)FileBuffer.MousePosition.Row - 1, + L"%c", + Value + ); + } + // + // end of HasCharacter + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } + // + // end of MouseNeedRefresh + // + } + // + // end of MouseSupported + // + return EFI_SUCCESS; +} + +/** + Free all the lines in FileBuffer + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferFreeLines ( + VOID + ) +{ + LIST_ENTRY *Link; + EFI_EDITOR_LINE *Line; + + // + // free all the lines + // + if (FileBuffer.Lines != NULL) { + + Line = FileBuffer.Lines; + Link = &(Line->Link); + do { + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + Link = Link->ForwardLink; + + // + // free line's buffer and line itself + // + LineFree (Line); + } while (Link != FileBuffer.ListHead); + } + // + // clean the line list related structure + // + FileBuffer.Lines = NULL; + FileBuffer.CurrentLine = NULL; + FileBuffer.NumLines = 0; + + FileBuffer.ListHead->ForwardLink = FileBuffer.ListHead; + FileBuffer.ListHead->BackLink = FileBuffer.ListHead; + + return EFI_SUCCESS; +} + +/** + Cleanup function for FileBuffer. + + @retval EFI_SUCCESS The cleanup was successful. +**/ +EFI_STATUS +FileBufferCleanup ( + VOID + ) +{ + EFI_STATUS Status; + + SHELL_FREE_NON_NULL (FileBuffer.FileName); + + // + // free all the lines + // + Status = FileBufferFreeLines (); + + SHELL_FREE_NON_NULL (FileBuffer.ListHead); + FileBuffer.ListHead = NULL; + + SHELL_FREE_NON_NULL (FileBufferBackupVar.FileName); + return Status; + +} + +/** + Print a line specified by Line on a row specified by Row of the screen. + + @param[in] Line The line to print. + @param[in] Row The row on the screen to print onto (begin from 1). + + @retval EFI_SUCCESS The printing was successful. +**/ +EFI_STATUS +FileBufferPrintLine ( + IN CONST EFI_EDITOR_LINE *Line, + IN CONST UINTN Row + ) +{ + + CHAR16 *Buffer; + UINTN Limit; + CHAR16 *PrintLine; + CHAR16 *PrintLine2; + UINTN BufLen; + + // + // print start from correct character + // + Buffer = Line->Buffer + FileBuffer.LowVisibleRange.Column - 1; + + Limit = Line->Size - FileBuffer.LowVisibleRange.Column + 1; + if (Limit > Line->Size) { + Limit = 0; + } + + BufLen = (MainEditor.ScreenSize.Column + 1) * sizeof (CHAR16); + PrintLine = AllocatePool (BufLen); + if (PrintLine != NULL) { + StrnCpyS (PrintLine, BufLen/sizeof(CHAR16), Buffer, MIN(Limit, MainEditor.ScreenSize.Column)); + for (Limit = StrLen (PrintLine); Limit < MainEditor.ScreenSize.Column; Limit++) { + PrintLine[Limit] = L' '; + } + + PrintLine[MainEditor.ScreenSize.Column] = CHAR_NULL; + + PrintLine2 = AllocatePool (BufLen * 2); + if (PrintLine2 != NULL) { + ShellCopySearchAndReplace(PrintLine, PrintLine2, BufLen * 2, L"%", L"^%", FALSE, FALSE); + + ShellPrintEx ( + 0, + (INT32)Row - 1, + L"%s", + PrintLine2 + ); + FreePool (PrintLine2); + } + FreePool (PrintLine); + } + + return EFI_SUCCESS; +} + +/** + Set the cursor position according to FileBuffer.DisplayPosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferRestorePosition ( + VOID + ) +{ + // + // set cursor position + // + return (gST->ConOut->SetCursorPosition ( + gST->ConOut, + FileBuffer.DisplayPosition.Column - 1, + FileBuffer.DisplayPosition.Row - 1 + )); +} + +/** + Refresh the screen with whats in the buffer. + + @retval EFI_SUCCESS The refresh was successful. + @retval EFI_LOAD_ERROR There was an error finding what to write. +**/ +EFI_STATUS +FileBufferRefresh ( + VOID + ) +{ + LIST_ENTRY *Link; + EFI_EDITOR_LINE *Line; + UINTN Row; + + // + // if it's the first time after editor launch, so should refresh + // + if (!EditorFirst) { + // + // no definite required refresh + // and file position displayed on screen has not been changed + // + if (!FileBufferNeedRefresh && + !FileBufferOnlyLineNeedRefresh && + FileBufferBackupVar.LowVisibleRange.Row == FileBuffer.LowVisibleRange.Row && + FileBufferBackupVar.LowVisibleRange.Column == FileBuffer.LowVisibleRange.Column + ) { + + FileBufferRestoreMousePosition (); + FileBufferRestorePosition (); + + return EFI_SUCCESS; + } + } + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + // + // only need to refresh current line + // + if (FileBufferOnlyLineNeedRefresh && + FileBufferBackupVar.LowVisibleRange.Row == FileBuffer.LowVisibleRange.Row && + FileBufferBackupVar.LowVisibleRange.Column == FileBuffer.LowVisibleRange.Column + ) { + + EditorClearLine (FileBuffer.DisplayPosition.Row, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row); + FileBufferPrintLine ( + FileBuffer.CurrentLine, + FileBuffer.DisplayPosition.Row + ); + } else { + // + // the whole edit area need refresh + // + + // + // no line + // + if (FileBuffer.Lines == NULL) { + FileBufferRestoreMousePosition (); + FileBufferRestorePosition (); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + return EFI_SUCCESS; + } + // + // get the first line that will be displayed + // + Line = MoveLine (FileBuffer.LowVisibleRange.Row - FileBuffer.FilePosition.Row); + if (Line == NULL) { + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + return EFI_LOAD_ERROR; + } + + Link = &(Line->Link); + Row = 2; + do { + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + // + // print line at row + // + FileBufferPrintLine (Line, Row); + + Link = Link->ForwardLink; + Row++; + } while (Link != FileBuffer.ListHead && Row <= (MainEditor.ScreenSize.Row - 1)); + // + // while not file end and not screen full + // + while (Row <= (MainEditor.ScreenSize.Row - 1)) { + EditorClearLine (Row, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row); + Row++; + } + } + + FileBufferRestoreMousePosition (); + FileBufferRestorePosition (); + + FileBufferNeedRefresh = FALSE; + FileBufferOnlyLineNeedRefresh = FALSE; + + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_SUCCESS; +} + +/** + Create a new line and append it to the line list. + Fields affected: + NumLines + Lines + + @retval NULL The create line failed. + @return The line created. +**/ +EFI_EDITOR_LINE * +FileBufferCreateLine ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + + // + // allocate a line structure + // + Line = AllocateZeroPool (sizeof (EFI_EDITOR_LINE)); + if (Line == NULL) { + return NULL; + } + // + // initialize the structure + // + Line->Signature = LINE_LIST_SIGNATURE; + Line->Size = 0; + Line->TotalSize = 0; + Line->Type = NewLineTypeDefault; + + // + // initial buffer of the line is "\0" + // + ASSERT(CHAR_NULL == CHAR_NULL); + Line->Buffer = CatSPrint (NULL, L"\0"); + if (Line->Buffer == NULL) { + return NULL; + } + + FileBuffer.NumLines++; + + // + // insert the line into line list + // + InsertTailList (FileBuffer.ListHead, &Line->Link); + + if (FileBuffer.Lines == NULL) { + FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + } + + return Line; +} + +/** + Set FileName field in FileBuffer. + + @param Str The file name to set. + + @retval EFI_SUCCESS The filename was successfully set. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_INVALID_PARAMETER Str is not a valid filename. +**/ +EFI_STATUS +FileBufferSetFileName ( + IN CONST CHAR16 *Str + ) +{ + // + // Verify the parameters + // + if (!IsValidFileName(Str)) { + return (EFI_INVALID_PARAMETER); + } + // + // free the old file name + // + SHELL_FREE_NON_NULL (FileBuffer.FileName); + + // + // Allocate and set the new name + // + FileBuffer.FileName = CatSPrint (NULL, L"%s", Str); + if (FileBuffer.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} +/** + Free the existing file lines and reset the modified flag. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferFree ( + VOID + ) +{ + // + // free all the lines + // + FileBufferFreeLines (); + FileBuffer.FileModified = FALSE; + + return EFI_SUCCESS; +} + + +/** + Read a file from disk into the FileBuffer. + + @param[in] FileName The filename to read. + @param[in] Recover TRUE if is for recover mode, no information printouts. + + @retval EFI_SUCCESS The load was successful. + @retval EFI_LOAD_ERROR The load failed. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_INVALID_PARAMETER FileName is a directory. +**/ +EFI_STATUS +FileBufferRead ( + IN CONST CHAR16 *FileName, + IN CONST BOOLEAN Recover + ) +{ + EFI_EDITOR_LINE *Line; + EE_NEWLINE_TYPE Type; + UINTN LoopVar1; + UINTN LoopVar2; + UINTN LineSize; + VOID *Buffer; + CHAR16 *UnicodeBuffer; + UINT8 *AsciiBuffer; + UINTN FileSize; + SHELL_FILE_HANDLE FileHandle; + BOOLEAN CreateFile; + EFI_STATUS Status; + UINTN LineSizeBackup; + EFI_FILE_INFO *Info; + + Line = NULL; + LoopVar1 = 0; + FileSize = 0; + UnicodeBuffer = NULL; + Type = NewLineTypeDefault; + FileHandle = NULL; + CreateFile = FALSE; + + // + // in this function, when you return error ( except EFI_OUT_OF_RESOURCES ) + // you should set status string via StatusBarSetStatusString(L"blah") + // since this function maybe called before the editorhandleinput loop + // so any error will cause editor return + // so if you want to print the error status + // you should set the status string + // + + // + // try to open the file + // + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + + if (!EFI_ERROR(Status)) { + CreateFile = FALSE; + if (FileHandle == NULL) { + StatusBarSetStatusString (L"Disk Error"); + return EFI_LOAD_ERROR; + } + + Info = ShellGetFileInfo(FileHandle); + + if (Info->Attribute & EFI_FILE_DIRECTORY) { + StatusBarSetStatusString (L"Directory Can Not Be Edited"); + FreePool (Info); + return EFI_INVALID_PARAMETER; + } + + if (Info->Attribute & EFI_FILE_READ_ONLY) { + FileBuffer.ReadOnly = TRUE; + } else { + FileBuffer.ReadOnly = FALSE; + } + // + // get file size + // + FileSize = (UINTN) Info->FileSize; + + FreePool (Info); + } else if (Status == EFI_NOT_FOUND) { + // + // file not exists. add create and try again + // + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + if (EFI_ERROR (Status)) { + if (Status == EFI_WRITE_PROTECTED || + Status == EFI_ACCESS_DENIED || + Status == EFI_NO_MEDIA || + Status == EFI_MEDIA_CHANGED + ) { + StatusBarSetStatusString (L"Access Denied"); + } else if (Status == EFI_DEVICE_ERROR || Status == EFI_VOLUME_CORRUPTED || Status == EFI_VOLUME_FULL) { + StatusBarSetStatusString (L"Disk Error"); + } else { + StatusBarSetStatusString (L"Invalid File Name or Current-working-directory"); + } + + return Status; + } else { + // + // it worked. now delete it and move on with the name (now validated) + // + Status = ShellDeleteFile (&FileHandle); + if (Status == EFI_WARN_DELETE_FAILURE) { + Status = EFI_ACCESS_DENIED; + } + FileHandle = NULL; + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Access Denied"); + return Status; + } + } + // + // file doesn't exist, so set CreateFile to TRUE + // + CreateFile = TRUE; + FileBuffer.ReadOnly = FALSE; + + // + // all the check ends + // so now begin to set file name, free lines + // + if (StrCmp (FileName, FileBuffer.FileName) != 0) { + FileBufferSetFileName (FileName); + } + // + // free the old lines + // + FileBufferFree (); + + } + // + // the file exists + // + if (!CreateFile) { + // + // allocate buffer to read file + // + Buffer = AllocateZeroPool (FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // read file into Buffer + // + Status = ShellReadFile (FileHandle, &FileSize, Buffer); + ShellCloseFile(&FileHandle); + FileHandle = NULL; + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read File Failed"); + SHELL_FREE_NON_NULL (Buffer); + return EFI_LOAD_ERROR; + } + // + // nothing in this file + // + if (FileSize == 0) { + SHELL_FREE_NON_NULL (Buffer); + // + // since has no head, so only can be an ASCII file + // + FileBuffer.FileType = FileTypeAscii; + + goto Done; + } + + AsciiBuffer = Buffer; + + if (FileSize < 2) { + // + // size < Unicode file header, so only can be ASCII file + // + FileBuffer.FileType = FileTypeAscii; + } else { + // + // Unicode file + // + if (*(UINT16 *) Buffer == EFI_UNICODE_BYTE_ORDER_MARK) { + // + // Unicode file's size should be even + // + if ((FileSize % 2) != 0) { + StatusBarSetStatusString (L"File Format Wrong"); + SHELL_FREE_NON_NULL (Buffer); + return EFI_LOAD_ERROR; + } + + FileSize /= 2; + + FileBuffer.FileType = FileTypeUnicode; + UnicodeBuffer = Buffer; + + // + // pass this 0xff and 0xfe + // + UnicodeBuffer++; + FileSize--; + } else { + FileBuffer.FileType = FileTypeAscii; + } + // + // end of AsciiBuffer == + // + } + // + // end of FileSize < 2 + // all the check ends + // so now begin to set file name, free lines + // + if (StrCmp (FileName, FileBuffer.FileName) != 0) { + FileBufferSetFileName (FileName); + } + + // + // free the old lines + // + FileBufferFree (); + + // + // parse file content line by line + // + for (LoopVar1 = 0; LoopVar1 < FileSize; LoopVar1++) { + Type = NewLineTypeUnknown; + + for (LineSize = LoopVar1; LineSize < FileSize; LineSize++) { + if (FileBuffer.FileType == FileTypeAscii) { + if (AsciiBuffer[LineSize] == CHAR_CARRIAGE_RETURN) { + Type = NewLineTypeCarriageReturn; + + // + // has LF following + // + if (LineSize < FileSize - 1) { + if (AsciiBuffer[LineSize + 1] == CHAR_LINEFEED) { + Type = NewLineTypeCarriageReturnLineFeed; + } + } + + break; + } else if (AsciiBuffer[LineSize] == CHAR_LINEFEED) { + Type = NewLineTypeLineFeed; + + // + // has CR following + // + if (LineSize < FileSize - 1) { + if (AsciiBuffer[LineSize + 1] == CHAR_CARRIAGE_RETURN) { + Type = NewLineTypeLineFeedCarriageReturn; + } + } + + break; + } + } else { + if (UnicodeBuffer[LineSize] == CHAR_CARRIAGE_RETURN) { + Type = NewLineTypeCarriageReturn; + + // + // has LF following + // + if (LineSize < FileSize - 1) { + if (UnicodeBuffer[LineSize + 1] == CHAR_LINEFEED) { + Type = NewLineTypeCarriageReturnLineFeed; + } + } + + break; + } else if (UnicodeBuffer[LineSize] == CHAR_LINEFEED) { + Type = NewLineTypeLineFeed; + + // + // has CR following + // + if (LineSize < FileSize - 1) { + if (UnicodeBuffer[LineSize + 1] == CHAR_CARRIAGE_RETURN) { + Type = NewLineTypeLineFeedCarriageReturn; + } + } + + break; + } + } + // + // endif == ASCII + // + } + // + // end of for LineSize + // + // if the type is wrong, then exit + // + if (Type == NewLineTypeUnknown) { + // + // Now if Type is NewLineTypeUnknown, it should be file end + // + Type = NewLineTypeDefault; + } + + LineSizeBackup = LineSize; + + // + // create a new line + // + Line = FileBufferCreateLine (); + if (Line == NULL) { + SHELL_FREE_NON_NULL (Buffer); + return EFI_OUT_OF_RESOURCES; + } + // + // calculate file length + // + LineSize -= LoopVar1; + + // + // Unicode and one CHAR_NULL + // + SHELL_FREE_NON_NULL (Line->Buffer); + Line->Buffer = AllocateZeroPool (LineSize * 2 + 2); + + if (Line->Buffer == NULL) { + RemoveEntryList (&Line->Link); + return EFI_OUT_OF_RESOURCES; + } + // + // copy this line to Line->Buffer + // + for (LoopVar2 = 0; LoopVar2 < LineSize; LoopVar2++) { + if (FileBuffer.FileType == FileTypeAscii) { + Line->Buffer[LoopVar2] = (CHAR16) AsciiBuffer[LoopVar1]; + } else { + Line->Buffer[LoopVar2] = UnicodeBuffer[LoopVar1]; + } + + LoopVar1++; + } + // + // LoopVar1 now points to where CHAR_CARRIAGE_RETURN or CHAR_LINEFEED; + // + Line->Buffer[LineSize] = 0; + + Line->Size = LineSize; + Line->TotalSize = LineSize; + Line->Type = Type; + + if (Type == NewLineTypeCarriageReturnLineFeed || Type == NewLineTypeLineFeedCarriageReturn) { + LoopVar1++; + } + + // + // last character is a return, SO create a new line + // + if (((Type == NewLineTypeCarriageReturnLineFeed || Type == NewLineTypeLineFeedCarriageReturn) && LineSizeBackup == FileSize - 2) || + ((Type == NewLineTypeLineFeed || Type == NewLineTypeCarriageReturn) && LineSizeBackup == FileSize - 1) + ) { + Line = FileBufferCreateLine (); + if (Line == NULL) { + SHELL_FREE_NON_NULL (Buffer); + return EFI_OUT_OF_RESOURCES; + } + } + // + // end of if + // + } + // + // end of LoopVar1 + // + SHELL_FREE_NON_NULL (Buffer); + + } + // + // end of if CreateFile + // +Done: + + FileBuffer.DisplayPosition.Row = 2; + FileBuffer.DisplayPosition.Column = 1; + FileBuffer.LowVisibleRange.Row = 1; + FileBuffer.LowVisibleRange.Column = 1; + FileBuffer.FilePosition.Row = 1; + FileBuffer.FilePosition.Column = 1; + FileBuffer.MousePosition.Row = 2; + FileBuffer.MousePosition.Column = 1; + + if (!Recover) { + UnicodeBuffer = CatSPrint (NULL, L"%d Lines Read", FileBuffer.NumLines); + if (UnicodeBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (UnicodeBuffer); + FreePool (UnicodeBuffer); + } +/* + // + // check whether we have fs?: in filename + // + LoopVar1 = 0; + FSMappingPtr = NULL; + while (FileName[LoopVar1] != 0) { + if (FileName[LoopVar1] == L':') { + FSMappingPtr = &FileName[LoopVar1]; + break; + } + + LoopVar1++; + } + + if (FSMappingPtr == NULL) { + CurDir = ShellGetCurrentDir (NULL); + } else { + LoopVar1 = 0; + LoopVar2 = 0; + while (FileName[LoopVar1] != 0) { + if (FileName[LoopVar1] == L':') { + break; + } + + FSMapping[LoopVar2++] = FileName[LoopVar1]; + + LoopVar1++; + } + + FSMapping[LoopVar2] = 0; + CurDir = ShellGetCurrentDir (FSMapping); + } + + if (CurDir != NULL) { + for (LoopVar1 = 0; LoopVar1 < StrLen (CurDir) && CurDir[LoopVar1] != ':'; LoopVar1++); + + CurDir[LoopVar1] = 0; + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ShellGetMap (CurDir); + FreePool (CurDir); + } else { + return EFI_LOAD_ERROR; + } + + Status = LibDevicePathToInterface ( + &gEfiSimpleFileSystemProtocolGuid, + DevicePath, + (VOID **) &Vol + ); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + Status = Vol->OpenVolume (Vol, &RootFs); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + // + // Get volume information of file system + // + Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + 100; + VolumeInfo = (EFI_FILE_SYSTEM_INFO *) AllocateZeroPool (Size); + Status = RootFs->GetInfo (RootFs, &gEfiFileSystemInfoGuid, &Size, VolumeInfo); + if (EFI_ERROR (Status)) { + RootFs->Close (RootFs); + return EFI_LOAD_ERROR; + } + + if (VolumeInfo->ReadOnly) { + StatusBarSetStatusString (L"WARNING: Volume Read Only"); + } + + FreePool (VolumeInfo); + RootFs->Close (RootFs); + } +// +*/ + // + // has line + // + if (FileBuffer.Lines != 0) { + FileBuffer.CurrentLine = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + } else { + // + // create a dummy line + // + Line = FileBufferCreateLine (); + if (Line == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + FileBuffer.CurrentLine = Line; + } + + FileBuffer.FileModified = FALSE; + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + FileBufferMouseNeedRefresh = TRUE; + + + return EFI_SUCCESS; +} + +/** + According to FileBuffer.NewLineType & FileBuffer.FileType, + get the return buffer and size. + + @param[in] Type The type of line. + @param[out] Buffer The buffer to fill. + @param[out] Size The amount of the buffer used on return. +**/ +VOID +GetNewLine ( + IN CONST EE_NEWLINE_TYPE Type, + OUT CHAR8 *Buffer, + OUT UINT8 *Size + ) +{ + UINT8 NewLineSize; + + // + // give new line buffer, + // and will judge unicode or ascii + // + NewLineSize = 0; + + // + // not legal new line type + // + if (Type != NewLineTypeLineFeed && Type != NewLineTypeCarriageReturn && Type != NewLineTypeCarriageReturnLineFeed && Type != NewLineTypeLineFeedCarriageReturn) { + *Size = 0; + return ; + } + // + // use_cr: give 0x0d + // + if (Type == NewLineTypeCarriageReturn) { + if (MainEditor.FileBuffer->FileType == FileTypeUnicode) { + Buffer[0] = 0x0d; + Buffer[1] = 0; + NewLineSize = 2; + } else { + Buffer[0] = 0x0d; + NewLineSize = 1; + } + + *Size = NewLineSize; + return ; + } + // + // use_lf: give 0x0a + // + if (Type == NewLineTypeLineFeed) { + if (MainEditor.FileBuffer->FileType == FileTypeUnicode) { + Buffer[0] = 0x0a; + Buffer[1] = 0; + NewLineSize = 2; + } else { + Buffer[0] = 0x0a; + NewLineSize = 1; + } + + *Size = NewLineSize; + return ; + } + // + // use_crlf: give 0x0d 0x0a + // + if (Type == NewLineTypeCarriageReturnLineFeed) { + if (MainEditor.FileBuffer->FileType == FileTypeUnicode) { + Buffer[0] = 0x0d; + Buffer[1] = 0; + Buffer[2] = 0x0a; + Buffer[3] = 0; + + NewLineSize = 4; + } else { + Buffer[0] = 0x0d; + Buffer[1] = 0x0a; + NewLineSize = 2; + } + + *Size = NewLineSize; + return ; + } + // + // use_lfcr: give 0x0a 0x0d + // + if (Type == NewLineTypeLineFeedCarriageReturn) { + if (MainEditor.FileBuffer->FileType == FileTypeUnicode) { + Buffer[0] = 0x0a; + Buffer[1] = 0; + Buffer[2] = 0x0d; + Buffer[3] = 0; + + NewLineSize = 4; + } else { + Buffer[0] = 0x0a; + Buffer[1] = 0x0d; + NewLineSize = 2; + } + + *Size = NewLineSize; + return ; + } + +} + +/** + Change a Unicode string to an ASCII string. + + @param[in] UStr The Unicode string. + @param[in] Length The maximum size of AStr. + @param[out] AStr ASCII string to pass out. + + @return The actuall length. +**/ +UINTN +UnicodeToAscii ( + IN CONST CHAR16 *UStr, + IN CONST UINTN Length, + OUT CHAR8 *AStr + ) +{ + UINTN Index; + + // + // just buffer copy, not character copy + // + for (Index = 0; Index < Length; Index++) { + *AStr++ = (CHAR8) *UStr++; + } + + return Index; +} + +/** + Save lines in FileBuffer to disk + + @param[in] FileName The file name for writing. + + @retval EFI_SUCCESS Data was written. + @retval EFI_LOAD_ERROR + @retval EFI_OUT_OF_RESOURCES There were not enough resources to write the file. +**/ +EFI_STATUS +FileBufferSave ( + IN CONST CHAR16 *FileName + ) +{ + SHELL_FILE_HANDLE FileHandle; + LIST_ENTRY *Link; + EFI_EDITOR_LINE *Line; + CHAR16 *Str; + + EFI_STATUS Status; + UINTN Length; + UINTN NumLines; + CHAR8 NewLineBuffer[4]; + UINT8 NewLineSize; + + EFI_FILE_INFO *Info; + + UINT64 Attribute; + + EE_NEWLINE_TYPE Type; + + UINTN TotalSize; + // + // 2M + // + CHAR8 *Cache; + UINTN LeftSize; + UINTN Size; + CHAR8 *Ptr; + + Length = 0; + // + // 2M + // + TotalSize = 0x200000; + + Attribute = 0; + + + + // + // if is the old file + // + if (FileBuffer.FileName != NULL && StrCmp (FileName, FileBuffer.FileName) == 0) { + // + // file has not been modified + // + if (!FileBuffer.FileModified) { + return EFI_SUCCESS; + } + + // + // if file is read-only, set error + // + if (FileBuffer.ReadOnly) { + StatusBarSetStatusString (L"Read Only File Can Not Be Saved"); + return EFI_SUCCESS; + } + } + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); + + if (!EFI_ERROR (Status)) { + Info = ShellGetFileInfo(FileHandle); + + if (Info != NULL && Info->Attribute & EFI_FILE_DIRECTORY) { + StatusBarSetStatusString (L"Directory Can Not Be Saved"); + ShellCloseFile (&FileHandle); + FreePool(Info); + return EFI_LOAD_ERROR; + } + + if (Info != NULL) { + Attribute = Info->Attribute & ~EFI_FILE_READ_ONLY; + FreePool(Info); + } + + // + // if file exits, so delete it + // + Status = ShellDeleteFile (&FileHandle); + if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) { + StatusBarSetStatusString (L"Write File Failed"); + return EFI_LOAD_ERROR; + } + } + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, Attribute); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Create File Failed"); + return EFI_LOAD_ERROR; + } + + // + // if file is Unicode file, write Unicode header to it. + // + if (FileBuffer.FileType == FileTypeUnicode) { + Length = 2; + Status = ShellWriteFile (FileHandle, &Length, (VOID*)&gUnicodeFileTag); + if (EFI_ERROR (Status)) { + ShellDeleteFile (&FileHandle); + return EFI_LOAD_ERROR; + } + } + + Cache = AllocateZeroPool (TotalSize); + if (Cache == NULL) { + ShellDeleteFile (&FileHandle); + return EFI_OUT_OF_RESOURCES; + } + + // + // write all the lines back to disk + // + NumLines = 0; + Type = NewLineTypeCarriageReturnLineFeed; + + Ptr = Cache; + LeftSize = TotalSize; + + for (Link = FileBuffer.ListHead->ForwardLink; Link != FileBuffer.ListHead; Link = Link->ForwardLink) { + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + if (Line->Type != NewLineTypeDefault) { + Type = Line->Type; + } + // + // newline character is at most 4 bytes ( two Unicode characters ) + // + Length = 4; + if (Line->Buffer != NULL && Line->Size != 0) { + if (FileBuffer.FileType == FileTypeAscii) { + Length += Line->Size; + } else { + Length += (Line->Size * 2); + } + // + // end if FileTypeAscii + // + } + + // + // no cache room left, so write cache to disk + // + if (LeftSize < Length) { + Size = TotalSize - LeftSize; + Status = ShellWriteFile (FileHandle, &Size, Cache); + if (EFI_ERROR (Status)) { + ShellDeleteFile (&FileHandle); + FreePool (Cache); + return EFI_LOAD_ERROR; + } + Ptr = Cache; + LeftSize = TotalSize; + } + + if (Line->Buffer != NULL && Line->Size != 0) { + if (FileBuffer.FileType == FileTypeAscii) { + UnicodeToAscii (Line->Buffer, Line->Size, Ptr); + Length = Line->Size; + } else { + Length = (Line->Size * 2); + CopyMem (Ptr, (CHAR8 *) Line->Buffer, Length); + } + // + // end if FileTypeAscii + // + Ptr += Length; + LeftSize -= Length; + + } + // + // end of if Line -> Buffer != NULL && Line -> Size != 0 + // + // if not the last line , write return buffer to disk + // + if (Link->ForwardLink != FileBuffer.ListHead) { + GetNewLine (Type, NewLineBuffer, &NewLineSize); + CopyMem (Ptr, (CHAR8 *) NewLineBuffer, NewLineSize); + + Ptr += NewLineSize; + LeftSize -= NewLineSize; + } + + NumLines++; + } + + if (TotalSize != LeftSize) { + Size = TotalSize - LeftSize; + Status = ShellWriteFile (FileHandle, &Size, Cache); + if (EFI_ERROR (Status)) { + ShellDeleteFile (&FileHandle); + FreePool (Cache); + return EFI_LOAD_ERROR; + } + } + + FreePool (Cache); + + ShellCloseFile(&FileHandle); + + FileBuffer.FileModified = FALSE; + + // + // set status string + // + Str = CatSPrint (NULL, L"%d Lines Written", NumLines); + if (Str == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (Str); + SHELL_FREE_NON_NULL (Str); + + // + // now everything is ready , you can set the new file name to filebuffer + // + if (FileName != NULL && FileBuffer.FileName != NULL && StrCmp (FileName, FileBuffer.FileName) != 0) { + // + // not the same + // + FileBufferSetFileName (FileName); + if (FileBuffer.FileName == NULL) { + ShellDeleteFile (&FileHandle); + return EFI_OUT_OF_RESOURCES; + } + } + + FileBuffer.ReadOnly = FALSE; + return EFI_SUCCESS; +} + +/** + Scroll cursor to left 1 character position. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferScrollLeft ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = FileBuffer.CurrentLine; + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // if already at start of this line, so move to the end of previous line + // + if (FCol <= 1) { + // + // has previous line + // + if (Line->Link.BackLink != FileBuffer.ListHead) { + FRow--; + Line = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + FCol = Line->Size + 1; + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at start of this line, just move to previous column + // + FCol--; + } + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Delete a char in line + + @param[in, out] Line The line to delete in. + @param[in] Pos Position to delete the char at ( start from 0 ). +**/ +VOID +LineDeleteAt ( + IN OUT EFI_EDITOR_LINE *Line, + IN UINTN Pos + ) +{ + UINTN Index; + + // + // move the latter characters front + // + for (Index = Pos - 1; Index < Line->Size; Index++) { + Line->Buffer[Index] = Line->Buffer[Index + 1]; + } + + Line->Size--; +} + +/** + Concatenate Src into Dest. + + @param[in, out] Dest Destination string + @param[in] Src Src String. +**/ +VOID +LineCat ( + IN OUT EFI_EDITOR_LINE *Dest, + IN EFI_EDITOR_LINE *Src + ) +{ + CHAR16 *Str; + UINTN Size; + + Size = Dest->Size; + + Dest->Buffer[Size] = 0; + + // + // concatenate the two strings + // + Str = CatSPrint (NULL, L"%s%s", Dest->Buffer, Src->Buffer); + if (Str == NULL) { + Dest->Buffer = NULL; + return ; + } + + Dest->Size = Size + Src->Size; + Dest->TotalSize = Dest->Size; + + FreePool (Dest->Buffer); + FreePool (Src->Buffer); + + // + // put str to dest->buffer + // + Dest->Buffer = Str; +} + +/** + Delete the previous character. + + @retval EFI_SUCCESS The delete was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferDoBackspace ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + EFI_EDITOR_LINE *End; + LIST_ENTRY *Link; + UINTN FileColumn; + + FileColumn = FileBuffer.FilePosition.Column; + + Line = FileBuffer.CurrentLine; + + // + // the first column + // + if (FileColumn == 1) { + // + // the first row + // + if (FileBuffer.FilePosition.Row == 1) { + return EFI_SUCCESS; + } + + FileBufferScrollLeft (); + + Line = FileBuffer.CurrentLine; + Link = Line->Link.ForwardLink; + End = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + // + // concatenate this line with previous line + // + LineCat (Line, End); + if (Line->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // remove End from line list + // + RemoveEntryList (&End->Link); + FreePool (End); + + FileBuffer.NumLines--; + + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + + } else { + // + // just delete the previous character + // + LineDeleteAt (Line, FileColumn - 1); + FileBufferScrollLeft (); + FileBufferOnlyLineNeedRefresh = TRUE; + } + + if (!FileBuffer.FileModified) { + FileBuffer.FileModified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Add a return into line at current position. + + @retval EFI_SUCCESS The insetrion of the character was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferDoReturn ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + EFI_EDITOR_LINE *NewLine; + UINTN FileColumn; + UINTN Index; + CHAR16 *Buffer; + UINTN Row; + UINTN Col; + + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + + Line = FileBuffer.CurrentLine; + + FileColumn = FileBuffer.FilePosition.Column; + + NewLine = AllocateZeroPool (sizeof (EFI_EDITOR_LINE)); + if (NewLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewLine->Signature = LINE_LIST_SIGNATURE; + NewLine->Size = Line->Size - FileColumn + 1; + NewLine->TotalSize = NewLine->Size; + NewLine->Buffer = CatSPrint (NULL, L"\0"); + if (NewLine->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewLine->Type = NewLineTypeDefault; + + if (NewLine->Size > 0) { + // + // UNICODE + CHAR_NULL + // + Buffer = AllocateZeroPool (2 * (NewLine->Size + 1)); + if (Buffer == NULL) { + FreePool (NewLine->Buffer); + FreePool (NewLine); + return EFI_OUT_OF_RESOURCES; + } + + FreePool (NewLine->Buffer); + + NewLine->Buffer = Buffer; + + for (Index = 0; Index < NewLine->Size; Index++) { + NewLine->Buffer[Index] = Line->Buffer[Index + FileColumn - 1]; + } + + NewLine->Buffer[NewLine->Size] = CHAR_NULL; + + Line->Buffer[FileColumn - 1] = CHAR_NULL; + Line->Size = FileColumn - 1; + } + // + // increase NumLines + // + FileBuffer.NumLines++; + + // + // insert it into the correct position of line list + // + NewLine->Link.BackLink = &(Line->Link); + NewLine->Link.ForwardLink = Line->Link.ForwardLink; + Line->Link.ForwardLink->BackLink = &(NewLine->Link); + Line->Link.ForwardLink = &(NewLine->Link); + + // + // move cursor to the start of next line + // + Row = FileBuffer.FilePosition.Row + 1; + Col = 1; + + FileBufferMovePosition (Row, Col); + + // + // set file is modified + // + if (!FileBuffer.FileModified) { + FileBuffer.FileModified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Delete current character from current line. This is the effect caused + by the 'del' key. + + @retval EFI_SUCCESS +**/ +EFI_STATUS +FileBufferDoDelete ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + EFI_EDITOR_LINE *Next; + LIST_ENTRY *Link; + UINTN FileColumn; + + Line = FileBuffer.CurrentLine; + FileColumn = FileBuffer.FilePosition.Column; + + // + // the last column + // + if (FileColumn >= Line->Size + 1) { + // + // the last line + // + if (Line->Link.ForwardLink == FileBuffer.ListHead) { + return EFI_SUCCESS; + } + // + // since last character, + // so will add the next line to this line + // + Link = Line->Link.ForwardLink; + Next = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + LineCat (Line, Next); + if (Line->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RemoveEntryList (&Next->Link); + FreePool (Next); + + FileBuffer.NumLines--; + + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + + } else { + // + // just delete current character + // + LineDeleteAt (Line, FileColumn); + FileBufferOnlyLineNeedRefresh = TRUE; + } + + if (!FileBuffer.FileModified) { + FileBuffer.FileModified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Scroll cursor to right 1 character. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferScrollRight ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = FileBuffer.CurrentLine; + if (Line->Buffer == NULL) { + return EFI_SUCCESS; + } + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // if already at end of this line, scroll it to the start of next line + // + if (FCol > Line->Size) { + // + // has next line + // + if (Line->Link.ForwardLink != FileBuffer.ListHead) { + FRow++; + FCol = 1; + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at end of this line, just move to next column + // + FCol++; + } + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Insert a char into line + + + @param[in] Line The line to insert into. + @param[in] Char The char to insert. + @param[in] Pos The position to insert the char at ( start from 0 ). + @param[in] StrSize The current string size ( include CHAR_NULL ),unit is Unicode character. + + @return The new string size ( include CHAR_NULL ) ( unit is Unicode character ). +**/ +UINTN +LineStrInsert ( + IN EFI_EDITOR_LINE *Line, + IN CHAR16 Char, + IN UINTN Pos, + IN UINTN StrSize + ) +{ + UINTN Index; + CHAR16 *TempStringPtr; + CHAR16 *Str; + + Index = (StrSize) * 2; + + Str = Line->Buffer; + + // + // do not have free space + // + if (Line->TotalSize <= Line->Size) { + Str = ReallocatePool (Index, Index + 16, Str); + if (Str == NULL) { + return 0; + } + + Line->TotalSize += 8; + } + // + // move the later part of the string one character right + // + TempStringPtr = Str; + for (Index = StrSize; Index > Pos; Index--) { + TempStringPtr[Index] = TempStringPtr[Index - 1]; + } + // + // insert char into it. + // + TempStringPtr[Index] = Char; + + Line->Buffer = Str; + Line->Size++; + + return StrSize + 1; +} + +/** + Add a character to the current line. + + @param[in] Char The Character to input. + + @retval EFI_SUCCESS The input was succesful. +**/ +EFI_STATUS +FileBufferAddChar ( + IN CHAR16 Char + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FilePos; + + Line = FileBuffer.CurrentLine; + + // + // only needs to refresh current line + // + FileBufferOnlyLineNeedRefresh = TRUE; + + // + // when is insert mode, or cursor is at end of this line, + // so insert this character + // or replace the character. + // + FilePos = FileBuffer.FilePosition.Column - 1; + if (FileBuffer.ModeInsert || FilePos + 1 > Line->Size) { + LineStrInsert (Line, Char, FilePos, Line->Size + 1); + } else { + Line->Buffer[FilePos] = Char; + } + // + // move cursor to right + // + FileBufferScrollRight (); + + if (!FileBuffer.FileModified) { + FileBuffer.FileModified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Handles inputs from characters (ASCII key + Backspace + return) + + @param[in] Char The input character. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR There was an error. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferDoCharInput ( + IN CONST CHAR16 Char + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Char) { + case CHAR_NULL: + break; + + case CHAR_BACKSPACE: + Status = FileBufferDoBackspace (); + break; + + case CHAR_TAB: + // + // Tabs are ignored + // + break; + + case CHAR_LINEFEED: + case CHAR_CARRIAGE_RETURN: + Status = FileBufferDoReturn (); + break; + + default: + // + // DEAL WITH ASCII CHAR, filter out thing like ctrl+f + // + if (Char > 127 || Char < 32) { + Status = StatusBarSetStatusString (L"Unknown Command"); + } else { + Status = FileBufferAddChar (Char); + } + + break; + + } + + return Status; +} + +/** + Scroll cursor to the next line. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferScrollDown ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = FileBuffer.CurrentLine; + if (Line->Buffer == NULL) { + return EFI_SUCCESS; + } + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // has next line + // + if (Line->Link.ForwardLink != FileBuffer.ListHead) { + FRow++; + Line = CR (Line->Link.ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + // + // if the next line is not that long, so move to end of next line + // + if (FCol > Line->Size) { + FCol = Line->Size + 1; + } + + } else { + return EFI_SUCCESS; + } + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Scroll the cursor to previous line. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferScrollUp ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = FileBuffer.CurrentLine; + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // has previous line + // + if (Line->Link.BackLink != FileBuffer.ListHead) { + FRow--; + Line = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + // + // if previous line is not that long, so move to the end of previous line + // + if (FCol > Line->Size) { + FCol = Line->Size + 1; + } + + } else { + return EFI_SUCCESS; + } + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to next page. + + @retval EFI_SUCCESS The operation wa successful. +**/ +EFI_STATUS +FileBufferPageDown ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + UINTN Gap; + + Line = FileBuffer.CurrentLine; + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // has next page + // + if (FileBuffer.NumLines >= FRow + (MainEditor.ScreenSize.Row - 2)) { + Gap = (MainEditor.ScreenSize.Row - 2); + } else { + // + // MOVE CURSOR TO LAST LINE + // + Gap = FileBuffer.NumLines - FRow; + } + // + // get correct line + // + Line = MoveLine (Gap); + + // + // if that line, is not that long, so move to the end of that line + // + if (Line != NULL && FCol > Line->Size) { + FCol = Line->Size + 1; + } + + FRow += Gap; + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to previous screen. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferPageUp ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + UINTN Gap; + INTN Retreat; + + Line = FileBuffer.CurrentLine; + + FRow = FileBuffer.FilePosition.Row; + FCol = FileBuffer.FilePosition.Column; + + // + // has previous page + // + if (FRow > (MainEditor.ScreenSize.Row - 2)) { + Gap = (MainEditor.ScreenSize.Row - 2); + } else { + // + // the first line of file will displayed on the first line of screen + // + Gap = FRow - 1; + } + + Retreat = Gap; + Retreat = -Retreat; + + // + // get correct line + // + Line = MoveLine (Retreat); + + // + // if that line is not that long, so move to the end of that line + // + if (Line != NULL && FCol > Line->Size) { + FCol = Line->Size + 1; + } + + FRow -= Gap; + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to end of the current line. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferEnd ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = FileBuffer.CurrentLine; + + FRow = FileBuffer.FilePosition.Row; + + // + // goto the last column of the line + // + FCol = Line->Size + 1; + + FileBufferMovePosition (FRow, FCol); + + return EFI_SUCCESS; +} + +/** + Dispatch input to different handler + @param[in] Key The input key. One of: + ASCII KEY + Backspace/Delete + Return + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The dispatch was done successfully. + @retval EFI_LOAD_ERROR The dispatch was not successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferHandleInput ( + IN CONST EFI_INPUT_KEY *Key + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Key->ScanCode) { + // + // ordinary key input + // + case SCAN_NULL: + if (!FileBuffer.ReadOnly) { + Status = FileBufferDoCharInput (Key->UnicodeChar); + } else { + Status = StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + } + + break; + + // + // up arrow + // + case SCAN_UP: + Status = FileBufferScrollUp (); + break; + + // + // down arrow + // + case SCAN_DOWN: + Status = FileBufferScrollDown (); + break; + + // + // right arrow + // + case SCAN_RIGHT: + Status = FileBufferScrollRight (); + break; + + // + // left arrow + // + case SCAN_LEFT: + Status = FileBufferScrollLeft (); + break; + + // + // page up + // + case SCAN_PAGE_UP: + Status = FileBufferPageUp (); + break; + + // + // page down + // + case SCAN_PAGE_DOWN: + Status = FileBufferPageDown (); + break; + + // + // delete + // + case SCAN_DELETE: + if (!FileBuffer.ReadOnly) { + Status = FileBufferDoDelete (); + } else { + Status = StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + } + + break; + + // + // home + // + case SCAN_HOME: + FileBufferMovePosition (FileBuffer.FilePosition.Row, 1); + Status = EFI_SUCCESS; + break; + + // + // end + // + case SCAN_END: + Status = FileBufferEnd (); + break; + + // + // insert + // + case SCAN_INSERT: + FileBuffer.ModeInsert = (BOOLEAN)!FileBuffer.ModeInsert; + Status = EFI_SUCCESS; + break; + + default: + Status = StatusBarSetStatusString (L"Unknown Command"); + break; + } + + return Status; +} + +/** + Check user specified FileRow is above current screen. + + @param[in] FileRow The row of file position ( start from 1 ). + + @retval TRUE It is above the current screen. + @retval FALSE It is not above the current screen. +**/ +BOOLEAN +AboveCurrentScreen ( + IN UINTN FileRow + ) +{ + // + // if is to the above of the screen + // + if (FileRow < FileBuffer.LowVisibleRange.Row) { + return TRUE; + } + + return FALSE; +} + +/** + Check user specified FileRow is under current screen. + + @param[in] FileRow The row of file position ( start from 1 ). + + @retval TRUE It is under the current screen. + @retval FALSE It is not under the current screen. +**/ +BOOLEAN +UnderCurrentScreen ( + IN UINTN FileRow + ) +{ + // + // if is to the under of the screen + // + if (FileRow > FileBuffer.LowVisibleRange.Row + (MainEditor.ScreenSize.Row - 2) - 1) { + return TRUE; + } + + return FALSE; +} + +/** + Check user specified FileCol is left to current screen. + + @param[in] FileCol The column of file position ( start from 1 ). + + @retval TRUE It is to the left. + @retval FALSE It is not to the left. +**/ +BOOLEAN +LeftCurrentScreen ( + IN UINTN FileCol + ) +{ + // + // if is to the left of the screen + // + if (FileCol < FileBuffer.LowVisibleRange.Column) { + return TRUE; + } + + return FALSE; +} + +/** + Check user specified FileCol is right to current screen. + + @param[in] FileCol The column of file position ( start from 1 ). + + @retval TRUE It is to the right. + @retval FALSE It is not to the right. +**/ +BOOLEAN +RightCurrentScreen ( + IN UINTN FileCol + ) +{ + // + // if is to the right of the screen + // + if (FileCol > FileBuffer.LowVisibleRange.Column + MainEditor.ScreenSize.Column - 1) { + return TRUE; + } + + return FALSE; +} + +/** + Advance/Retreat lines and set CurrentLine in FileBuffer to it + + @param[in] Count The line number to advance/retreat + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return The line after advance/retreat. +**/ +EFI_EDITOR_LINE * +MoveCurrentLine ( + IN INTN Count + ) +{ + EFI_EDITOR_LINE *Line; + UINTN AbsCount; + + if (Count <= 0) { + AbsCount = (UINTN)ABS(Count); + Line = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead); + } else { + Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead); + } + + if (Line == NULL) { + return NULL; + } + + MainEditor.FileBuffer->CurrentLine = Line; + + return Line; +} + +/** + According to cursor's file position, adjust screen display + + @param[in] NewFilePosRow The row of file position ( start from 1 ). + @param[in] NewFilePosCol The column of file position ( start from 1 ). +**/ +VOID +FileBufferMovePosition ( + IN CONST UINTN NewFilePosRow, + IN CONST UINTN NewFilePosCol + ) +{ + INTN RowGap; + INTN ColGap; + UINTN Abs; + BOOLEAN Above; + BOOLEAN Under; + BOOLEAN Right; + BOOLEAN Left; + + // + // CALCULATE gap between current file position and new file position + // + RowGap = NewFilePosRow - FileBuffer.FilePosition.Row; + ColGap = NewFilePosCol - FileBuffer.FilePosition.Column; + + Under = UnderCurrentScreen (NewFilePosRow); + Above = AboveCurrentScreen (NewFilePosRow); + // + // if is below current screen + // + if (Under) { + // + // display row will be unchanged + // + FileBuffer.FilePosition.Row = NewFilePosRow; + } else { + if (Above) { + // + // has enough above line, so display row unchanged + // not has enough above lines, so the first line is at the + // first display line + // + if (NewFilePosRow < (FileBuffer.DisplayPosition.Row - 1)) { + FileBuffer.DisplayPosition.Row = NewFilePosRow + 1; + } + + FileBuffer.FilePosition.Row = NewFilePosRow; + } else { + // + // in current screen + // + FileBuffer.FilePosition.Row = NewFilePosRow; + if (RowGap < 0) { + Abs = (UINTN)ABS(RowGap); + FileBuffer.DisplayPosition.Row -= Abs; + } else { + FileBuffer.DisplayPosition.Row += RowGap; + } + } + } + + FileBuffer.LowVisibleRange.Row = FileBuffer.FilePosition.Row - (FileBuffer.DisplayPosition.Row - 2); + + Right = RightCurrentScreen (NewFilePosCol); + Left = LeftCurrentScreen (NewFilePosCol); + + // + // if right to current screen + // + if (Right) { + // + // display column will be changed to end + // + FileBuffer.DisplayPosition.Column = MainEditor.ScreenSize.Column; + FileBuffer.FilePosition.Column = NewFilePosCol; + } else { + if (Left) { + // + // has enough left characters , so display row unchanged + // not has enough left characters, + // so the first character is at the first display column + // + if (NewFilePosCol < (FileBuffer.DisplayPosition.Column)) { + FileBuffer.DisplayPosition.Column = NewFilePosCol; + } + + FileBuffer.FilePosition.Column = NewFilePosCol; + } else { + // + // in current screen + // + FileBuffer.FilePosition.Column = NewFilePosCol; + if (ColGap < 0) { + Abs = (UINTN)(-ColGap); + FileBuffer.DisplayPosition.Column -= Abs; + } else { + FileBuffer.DisplayPosition.Column += ColGap; + } + } + } + + FileBuffer.LowVisibleRange.Column = FileBuffer.FilePosition.Column - (FileBuffer.DisplayPosition.Column - 1); + + // + // let CurrentLine point to correct line; + // + FileBuffer.CurrentLine = MoveCurrentLine (RowGap); + +} + +/** + Cut current line out and return a pointer to it. + + @param[out] CutLine Upon a successful return pointer to the pointer to + the allocated cut line. + + @retval EFI_SUCCESS The cut was successful. + @retval EFI_NOT_FOUND There was no selection to cut. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferCutLine ( + OUT EFI_EDITOR_LINE **CutLine + ) +{ + EFI_EDITOR_LINE *Line; + EFI_EDITOR_LINE *NewLine; + UINTN Row; + UINTN Col; + + *CutLine = NULL; + + if (FileBuffer.ReadOnly) { + StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + return EFI_SUCCESS; + } + + Line = FileBuffer.CurrentLine; + + // + // if is the last dummy line, SO CAN not cut + // + if (StrCmp (Line->Buffer, L"\0") == 0 && Line->Link.ForwardLink == FileBuffer.ListHead + // + // last line + // + ) { + // + // LAST LINE AND NOTHING ON THIS LINE, SO CUT NOTHING + // + StatusBarSetStatusString (L"Nothing to Cut"); + return EFI_NOT_FOUND; + } + // + // if is the last line, so create a dummy line + // + if (Line->Link.ForwardLink == FileBuffer.ListHead) { + // + // last line + // create a new line + // + NewLine = FileBufferCreateLine (); + if (NewLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + FileBuffer.NumLines--; + Row = FileBuffer.FilePosition.Row; + Col = 1; + // + // move home + // + FileBuffer.CurrentLine = CR ( + FileBuffer.CurrentLine->Link.ForwardLink, + EFI_EDITOR_LINE, + Link, + LINE_LIST_SIGNATURE + ); + + RemoveEntryList (&Line->Link); + + FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + FileBufferMovePosition (Row, Col); + + FileBuffer.FileModified = TRUE; + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + + *CutLine = Line; + + return EFI_SUCCESS; +} + +/** + Paste a line into line list. + + @retval EFI_SUCCESS The paste was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferPasteLine ( + VOID + ) +{ + EFI_EDITOR_LINE *Line; + EFI_EDITOR_LINE *NewLine; + UINTN Row; + UINTN Col; + + // + // if nothing is on clip board + // then do nothing + // + if (MainEditor.CutLine == NULL) { + return EFI_SUCCESS; + } + // + // read only file can not be pasted on + // + if (FileBuffer.ReadOnly) { + StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + return EFI_SUCCESS; + } + + NewLine = LineDup (MainEditor.CutLine); + if (NewLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // insert it above current line + // + Line = FileBuffer.CurrentLine; + NewLine->Link.BackLink = Line->Link.BackLink; + NewLine->Link.ForwardLink = &Line->Link; + + Line->Link.BackLink->ForwardLink = &NewLine->Link; + Line->Link.BackLink = &NewLine->Link; + + FileBuffer.NumLines++; + FileBuffer.CurrentLine = NewLine; + + FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + Col = 1; + // + // move home + // + Row = FileBuffer.FilePosition.Row; + + FileBufferMovePosition (Row, Col); + + // + // after paste, set some value so that refresh knows to do something + // + FileBuffer.FileModified = TRUE; + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + + return EFI_SUCCESS; +} + +/** + Search string from current position on in file + + @param[in] Str The search string. + @param[in] Offset The offset from current position. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_NOT_FOUND The string Str was not found. +**/ +EFI_STATUS +FileBufferSearch ( + IN CONST CHAR16 *Str, + IN CONST UINTN Offset + ) +{ + CHAR16 *Current; + UINTN Position; + UINTN Row; + UINTN Column; + EFI_EDITOR_LINE *Line; + CHAR16 *CharPos; + LIST_ENTRY *Link; + BOOLEAN Found; + + Column = 0; + Position = 0; + + // + // search if in current line + // + Current = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1 + Offset; + + if (Current >= (FileBuffer.CurrentLine->Buffer + FileBuffer.CurrentLine->Size)) { + // + // the end + // + Current = FileBuffer.CurrentLine->Buffer + FileBuffer.CurrentLine->Size; + } + + Found = FALSE; + + CharPos = StrStr (Current, Str); + if (CharPos != NULL) { + Position = CharPos - Current + 1; + Found = TRUE; + } + + // + // found + // + if (Found) { + Column = (Position - 1) + FileBuffer.FilePosition.Column + Offset; + Row = FileBuffer.FilePosition.Row; + } else { + // + // not found so find through next lines + // + Link = FileBuffer.CurrentLine->Link.ForwardLink; + + Row = FileBuffer.FilePosition.Row + 1; + while (Link != FileBuffer.ListHead) { + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); +// Position = StrStr (Line->Buffer, Str); + CharPos = StrStr (Line->Buffer, Str); + if (CharPos != NULL) { + Position = CharPos - Line->Buffer + 1; + Found = TRUE; + } + + if (Found) { + // + // found + // + Column = Position; + break; + } + + Row++; + Link = Link->ForwardLink; + } + + if (Link == FileBuffer.ListHead) { + Found = FALSE; + } else { + Found = TRUE; + } + } + + if (!Found) { + return EFI_NOT_FOUND; + } + + FileBufferMovePosition (Row, Column); + + // + // call refresh to fresh edit area, + // because the outer may loop to find multiply occurrence of this string + // + FileBufferRefresh (); + + return EFI_SUCCESS; +} + +/** + Replace SearchLen characters from current position on with Replace. + + This will modify the current buffer at the current position. + + @param[in] Replace The string to replace. + @param[in] SearchLen Search string's length. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferReplace ( + IN CONST CHAR16 *Replace, + IN CONST UINTN SearchLen + ) +{ + UINTN ReplaceLen; + UINTN Index; + CHAR16 *Buffer; + UINTN NewSize; + UINTN OldSize; + UINTN Gap; + + ReplaceLen = StrLen (Replace); + + OldSize = FileBuffer.CurrentLine->Size + 1; + // + // include CHAR_NULL + // + NewSize = OldSize + (ReplaceLen - SearchLen); + + if (ReplaceLen > SearchLen) { + // + // do not have the enough space + // + if (FileBuffer.CurrentLine->TotalSize + 1 <= NewSize) { + FileBuffer.CurrentLine->Buffer = ReallocatePool ( + 2 * OldSize, + 2 * NewSize, + FileBuffer.CurrentLine->Buffer + ); + FileBuffer.CurrentLine->TotalSize = NewSize - 1; + } + + if (FileBuffer.CurrentLine->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // the end CHAR_NULL character; + // + Buffer = FileBuffer.CurrentLine->Buffer + (NewSize - 1); + Gap = ReplaceLen - SearchLen; + + // + // keep the latter part + // + for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - SearchLen + 2); Index++) { + *Buffer = *(Buffer - Gap); + Buffer--; + } + // + // set replace into it + // + Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1; + for (Index = 0; Index < ReplaceLen; Index++) { + Buffer[Index] = Replace[Index]; + } + } + + if (ReplaceLen < SearchLen) { + Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1; + + for (Index = 0; Index < ReplaceLen; Index++) { + Buffer[Index] = Replace[Index]; + } + + Buffer += ReplaceLen; + Gap = SearchLen - ReplaceLen; + + // + // set replace into it + // + for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - ReplaceLen + 2); Index++) { + *Buffer = *(Buffer + Gap); + Buffer++; + } + } + + if (ReplaceLen == SearchLen) { + Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1; + for (Index = 0; Index < ReplaceLen; Index++) { + Buffer[Index] = Replace[Index]; + } + } + + FileBuffer.CurrentLine->Size += (ReplaceLen - SearchLen); + + FileBufferOnlyLineNeedRefresh = TRUE; + + FileBuffer.FileModified = TRUE; + + MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0); + FileBufferRestorePosition (); + FileBufferRefresh (); + + return EFI_SUCCESS; +} + +/** + Move the mouse cursor position. + + @param[in] TextX The new x-coordinate. + @param[in] TextY The new y-coordinate. +**/ +VOID +FileBufferAdjustMousePosition ( + IN CONST INT32 TextX, + IN CONST INT32 TextY + ) +{ + UINTN CoordinateX; + UINTN CoordinateY; + UINTN AbsX; + UINTN AbsY; + + // + // TextX and TextY is mouse movement data returned by mouse driver + // This function will change it to MousePosition + // + // + // get absolute value + // + + AbsX = ABS(TextX); + AbsY = ABS(TextY); + + CoordinateX = FileBuffer.MousePosition.Column; + CoordinateY = FileBuffer.MousePosition.Row; + + if (TextX >= 0) { + CoordinateX += TextX; + } else { + if (CoordinateX >= AbsX) { + CoordinateX -= AbsX; + } else { + CoordinateX = 0; + } + } + + if (TextY >= 0) { + CoordinateY += TextY; + } else { + if (CoordinateY >= AbsY) { + CoordinateY -= AbsY; + } else { + CoordinateY = 0; + } + } + // + // check whether new mouse column position is beyond screen + // if not, adjust it + // + if (CoordinateX >= 1 && CoordinateX <= MainEditor.ScreenSize.Column) { + FileBuffer.MousePosition.Column = CoordinateX; + } else if (CoordinateX < 1) { + FileBuffer.MousePosition.Column = 1; + } else if (CoordinateX > MainEditor.ScreenSize.Column) { + FileBuffer.MousePosition.Column = MainEditor.ScreenSize.Column; + } + // + // check whether new mouse row position is beyond screen + // if not, adjust it + // + if (CoordinateY >= 2 && CoordinateY <= (MainEditor.ScreenSize.Row - 1)) { + FileBuffer.MousePosition.Row = CoordinateY; + } else if (CoordinateY < 2) { + FileBuffer.MousePosition.Row = 2; + } else if (CoordinateY > (MainEditor.ScreenSize.Row - 1)) { + FileBuffer.MousePosition.Row = (MainEditor.ScreenSize.Row - 1); + } + +} + +/** + Search and replace operation. + + @param[in] SearchStr The string to search for. + @param[in] ReplaceStr The string to replace with. + @param[in] Offset The column to start at. +**/ +EFI_STATUS +FileBufferReplaceAll ( + IN CHAR16 *SearchStr, + IN CHAR16 *ReplaceStr, + IN UINTN Offset + ) +{ + CHAR16 *Buffer; + UINTN Position; + UINTN Column; + UINTN ReplaceLen; + UINTN SearchLen; + UINTN Index; + UINTN NewSize; + UINTN OldSize; + UINTN Gap; + EFI_EDITOR_LINE *Line; + LIST_ENTRY *Link; + CHAR16 *CharPos; + + SearchLen = StrLen (SearchStr); + ReplaceLen = StrLen (ReplaceStr); + + Column = FileBuffer.FilePosition.Column + Offset - 1; + + if (Column > FileBuffer.CurrentLine->Size) { + Column = FileBuffer.CurrentLine->Size; + } + + Link = &(FileBuffer.CurrentLine->Link); + + while (Link != FileBuffer.ListHead) { + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + CharPos = StrStr (Line->Buffer + Column, SearchStr); + if (CharPos != NULL) { + Position = CharPos - Line->Buffer;// + Column; + // + // found + // + if (ReplaceLen > SearchLen) { + OldSize = Line->Size + 1; + // + // include CHAR_NULL + // + NewSize = OldSize + (ReplaceLen - SearchLen); + + // + // do not have the enough space + // + if (Line->TotalSize + 1 <= NewSize) { + Line->Buffer = ReallocatePool ( + 2 * OldSize, + 2 * NewSize, + Line->Buffer + ); + Line->TotalSize = NewSize - 1; + } + + if (Line->Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // the end CHAR_NULL character; + // + Buffer = Line->Buffer + (NewSize - 1); + Gap = ReplaceLen - SearchLen; + + // + // keep the latter part + // + for (Index = 0; Index < (Line->Size - Position - SearchLen + 1); Index++) { + *Buffer = *(Buffer - Gap); + Buffer--; + } + + } else if (ReplaceLen < SearchLen){ + Buffer = Line->Buffer + Position + ReplaceLen; + Gap = SearchLen - ReplaceLen; + + for (Index = 0; Index < (Line->Size - Position - ReplaceLen + 1); Index++) { + *Buffer = *(Buffer + Gap); + Buffer++; + } + } else { + ASSERT(ReplaceLen == SearchLen); + } + // + // set replace into it + // + Buffer = Line->Buffer + Position; + for (Index = 0; Index < ReplaceLen; Index++) { + Buffer[Index] = ReplaceStr[Index]; + } + + Line->Size += (ReplaceLen - SearchLen); + Column += ReplaceLen; + } else { + // + // not found + // + Column = 0; + Link = Link->ForwardLink; + } + } + // + // call refresh to fresh edit area + // + FileBuffer.FileModified = TRUE; + FileBufferNeedRefresh = TRUE; + FileBufferRefresh (); + + return EFI_SUCCESS; +} + +/** + Set the modified state to TRUE. +**/ +VOID +FileBufferSetModified ( + VOID + ) +{ + FileBuffer.FileModified = TRUE; +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.h new file mode 100644 index 00000000..c1da4d31 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/FileBuffer.h @@ -0,0 +1,240 @@ +/** @file + Declares filebuffer interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_FILE_BUFFER_H_ +#define _LIB_FILE_BUFFER_H_ + +#include "TextEditorTypes.h" + +/** + Initialization function for FileBuffer. + + @param EFI_SUCCESS The initialization was successful. + @param EFI_LOAD_ERROR A default name could not be created. + @param EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferInit ( + VOID + ); + +/** + Cleanup function for FileBuffer. + + @retval EFI_SUCCESS The cleanup was successful. +**/ +EFI_STATUS +FileBufferCleanup ( + VOID + ); + +/** + Refresh the screen with whats in the buffer. + + @retval EFI_SUCCESS The refresh was successful. + @retval EFI_LOAD_ERROR There was an error finding what to write. +**/ +EFI_STATUS +FileBufferRefresh ( + VOID + ); + +/** + Dispatch input to different handler + @param[in] Key The input key. One of: + ASCII KEY + Backspace/Delete + Return + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The dispatch was done successfully. + @retval EFI_LOAD_ERROR The dispatch was not successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferHandleInput ( + IN CONST EFI_INPUT_KEY * Key + ); + +/** + Backup function for FileBuffer. Only backup the following items: + Mouse/Cursor position + File Name, Type, ReadOnly, Modified + Insert Mode + + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The backup operation was successful. +**/ +EFI_STATUS +FileBufferBackup ( + VOID + ); + +/** + Set the cursor position according to FileBuffer.DisplayPosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +FileBufferRestorePosition ( + VOID + ); + +/** + Set FileName field in FileBuffer. + + @param Str The file name to set. + + @retval EFI_SUCCESS The filename was successfully set. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_INVALID_PARAMETER Str is not a valid filename. +**/ +EFI_STATUS +FileBufferSetFileName ( + IN CONST CHAR16 *Str + ); + +/** + Read a file from disk into the FileBuffer. + + @param[in] FileName The filename to read. + @param[in] Recover TRUE if is for recover mode, no information printouts. + + @retval EFI_SUCCESS The load was successful. + @retval EFI_LOAD_ERROR The load failed. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_INVALID_PARAMETER FileName is a directory. +**/ +EFI_STATUS +FileBufferRead ( + IN CONST CHAR16 *FileName, + IN CONST BOOLEAN Recover + ); + +/** + Save lines in FileBuffer to disk + + @param[in] FileName The file name for writing. + + @retval EFI_SUCCESS Data was written. + @retval EFI_LOAD_ERROR + @retval EFI_OUT_OF_RESOURCES There were not enough resources to write the file. +**/ +EFI_STATUS +FileBufferSave ( + CONST CHAR16 *FileName + ); + +/** + According to cursor's file position, adjust screen display + + @param[in] NewFilePosRow The row of file position ( start from 1 ). + @param[in] NewFilePosCol The column of file position ( start from 1 ). +**/ +VOID +FileBufferMovePosition ( + IN CONST UINTN NewFilePosRow, + IN CONST UINTN NewFilePosCol + ); + +/** + Cut current line out and return a pointer to it. + + @param[out] CutLine Upon a successful return pointer to the pointer to + the allocated cut line. + + @retval EFI_SUCCESS The cut was successful. + @retval EFI_NOT_FOUND There was no selection to cut. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferCutLine ( + OUT EFI_EDITOR_LINE **CutLine + ); + +/** + Paste a line into line list. + + @retval EFI_SUCCESS The paste was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferPasteLine ( + VOID + ); + +/** + Search string from current position on in file + + @param[in] Str The search string. + @param[in] Offset The offset from current position. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_NOT_FOUND The string Str was not found. +**/ +EFI_STATUS +FileBufferSearch ( + IN CONST CHAR16 *Str, + IN CONST UINTN Offset + ); + +/** + Replace SearchLen characters from current position on with Replace. + + This will modify the current buffer at the current position. + + @param[in] Replace The string to replace. + @param[in] SearchLen Search string's length. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +FileBufferReplace ( + IN CONST CHAR16 *Replace, + IN CONST UINTN SearchLen + ); + +/** + Search and replace operation. + + @param[in] SearchStr The string to search for. + @param[in] ReplaceStr The string to replace with. + @param[in] Offset The column to start at. +**/ +EFI_STATUS +FileBufferReplaceAll ( + IN CHAR16 *SearchStr, + IN CHAR16 *ReplaceStr, + IN UINTN Offset + ); + +/** + Move the mouse cursor position. + + @param[in] TextX The new x-coordinate. + @param[in] TextY The new y-coordinate. +**/ +VOID +FileBufferAdjustMousePosition ( + IN CONST INT32 TextX, + IN CONST INT32 TextY + ); + +/** + Set the modified state to TRUE. +**/ +VOID +FileBufferSetModified ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c new file mode 100644 index 00000000..3c3c587d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c @@ -0,0 +1,1974 @@ +/** @file + Implements editor interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "TextEditor.h" +#include "EditStatusBar.h" +#include "EditInputBar.h" +#include "EditMenuBar.h" + +// +// the first time editor launch +// +BOOLEAN EditorFirst; + +// +// it's time editor should exit +// +BOOLEAN EditorExit; + +BOOLEAN EditorMouseAction; + +extern EFI_EDITOR_FILE_BUFFER FileBuffer; + +extern BOOLEAN FileBufferNeedRefresh; + +extern BOOLEAN FileBufferOnlyLineNeedRefresh; + +extern BOOLEAN FileBufferMouseNeedRefresh; + +extern EFI_EDITOR_FILE_BUFFER FileBufferBackupVar; + +EFI_EDITOR_GLOBAL_EDITOR MainEditor; + + +/** + Load a file from disk to editor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainCommandOpenFile ( + VOID + ); + +/** + Switch a file from ASCII to UNICODE or vise-versa. + + @retval EFI_SUCCESS The switch was ok or a warning was presented. +**/ +EFI_STATUS +MainCommandSwitchFileType ( + VOID + ); + +/** + move cursor to specified lines + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainCommandGotoLine ( + VOID + ); + +/** + Save current file to disk, you can save to current file name or + save to another file name. + + @retval EFI_SUCCESS The file was saved correctly. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A file access error occurred. +**/ +EFI_STATUS +MainCommandSaveFile ( + VOID + ); + +/** + Show help information for the editor. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainCommandDisplayHelp ( + VOID + ); + +/** + exit editor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandExit ( + VOID + ); + +/** + search string in file buffer + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandSearch ( + VOID + ); + +/** + search string in file buffer, and replace it with another str + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandSearchReplace ( + VOID + ); + +/** + cut current line to clipboard + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandCutLine ( + VOID + ); + +/** + paste line to file buffer. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandPasteLine ( + VOID + ); + +/** + Help info that will be displayed. +**/ +EFI_STRING_ID MainMenuHelpInfo[] = { + STRING_TOKEN(STR_EDIT_HELP_TITLE), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_LIST_TITLE), + STRING_TOKEN(STR_EDIT_HELP_DIV), + STRING_TOKEN(STR_EDIT_HELP_GO_TO_LINE), + STRING_TOKEN(STR_EDIT_HELP_SAVE_FILE), + STRING_TOKEN(STR_EDIT_HELP_EXIT), + STRING_TOKEN(STR_EDIT_HELP_SEARCH), + STRING_TOKEN(STR_EDIT_HELP_SEARCH_REPLACE), + STRING_TOKEN(STR_EDIT_HELP_CUT_LINE), + STRING_TOKEN(STR_EDIT_HELP_PASTE_LINE), + STRING_TOKEN(STR_EDIT_HELP_OPEN_FILE), + STRING_TOKEN(STR_EDIT_HELP_FILE_TYPE), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_EXIT_HELP), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_BLANK), + STRING_TOKEN(STR_EDIT_HELP_DIV), +0 +}; + +MENU_ITEM_FUNCTION MainControlBasedMenuFunctions[] = { + NULL, + NULL, /* Ctrl - A */ + NULL, /* Ctrl - B */ + NULL, /* Ctrl - C */ + NULL, /* Ctrl - D */ + MainCommandDisplayHelp, /* Ctrl - E */ + MainCommandSearch, /* Ctrl - F */ + MainCommandGotoLine, /* Ctrl - G */ + NULL, /* Ctrl - H */ + NULL, /* Ctrl - I */ + NULL, /* Ctrl - J */ + MainCommandCutLine, /* Ctrl - K */ + NULL, /* Ctrl - L */ + NULL, /* Ctrl - M */ + NULL, /* Ctrl - N */ + MainCommandOpenFile, /* Ctrl - O */ + NULL, /* Ctrl - P */ + MainCommandExit, /* Ctrl - Q */ + MainCommandSearchReplace, /* Ctrl - R */ + MainCommandSaveFile, /* Ctrl - S */ + MainCommandSwitchFileType, /* Ctrl - T */ + MainCommandPasteLine, /* Ctrl - U */ + NULL, /* Ctrl - V */ + NULL, /* Ctrl - W */ + NULL, /* Ctrl - X */ + NULL, /* Ctrl - Y */ + NULL, /* Ctrl - Z */ +}; + +EDITOR_MENU_ITEM MainMenuItems[] = { + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_GO_TO_LINE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1), + MainCommandGotoLine + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_SAVE_FILE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2), + MainCommandSaveFile + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3), + MainCommandExit + }, + + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4), + MainCommandSearch + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH_REPLACE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5), + MainCommandSearchReplace + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_CUT_LINE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6), + MainCommandCutLine + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_PASTE_LINE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7), + MainCommandPasteLine + }, + + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_OPEN_FILE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8), + MainCommandOpenFile + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9), + MainCommandSwitchFileType + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F11), + MainCommandSwitchFileType + }, + + { + 0, + 0, + NULL + } +}; + + +/** + Load a file from disk to editor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainCommandOpenFile ( + VOID + ) +{ + BOOLEAN Done; + EFI_STATUS Status; + + // + // This command will open a file from current working directory. + // Read-only file can also be opened. But it can not be modified. + // Below is the scenario of Open File command: + // 1.IF currently opened file has not been modIFied, directly go to step . + // IF currently opened file has been modified, + // an Input Bar will be prompted as : + // "File Modified. Save ( Yes/No/Cancel) ?" + // IF user press 'y' or 'Y', currently opened file will be saved. + // IF user press 'n' or 'N', currently opened file will + // not be saved. + // IF user press 'c' or 'C' or ESC, Open File command ends and + // currently opened file is still opened. + // + // 2. An Input Bar will be prompted as : "File Name to Open: " + // IF user press ESC, Open File command ends and + // currently opened file is still opened. + // Any other inputs with a Return will + // cause currently opened file close. + // + // 3. IF user input file name is an existing file , this file will be read + // and opened. + // IF user input file name is a new file, this file will be created + // and opened. This file's type ( UNICODE or ASCII ) is the same + // with the old file. + // if current file is modified, so you need to choose + // whether to save it first. + // + if (MainEditor.FileBuffer->FileModified) { + + Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // the answer is just one character + // + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + // + // loop for user's answer + // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' + // + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // want to save this file first + // + Status = FileBufferSave (MainEditor.FileBuffer->FileName); + if (EFI_ERROR (Status)) { + return Status; + } + + MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0); + FileBufferRestorePosition (); + Done = TRUE; + break; + + case L'n': + case L'N': + // + // the file won't be saved + // + Done = TRUE; + break; + + case L'c': + case L'C': + return EFI_SUCCESS; + } + } + } + // + // TO get the open file name + // + Status = InputBarSetPrompt (L"File Name to Open: "); + if (EFI_ERROR (Status)) { + FileBufferRead (MainEditor.FileBuffer->FileName, TRUE); + return Status; + } + + Status = InputBarSetStringSize (100); + if (EFI_ERROR (Status)) { + FileBufferRead (MainEditor.FileBuffer->FileName, TRUE); + return Status; + } + + while (1) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + // + // The input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + // + // CHECK if filename is valid + // + if (!IsValidFileName (InputBarGetString())) { + FileBufferRead (MainEditor.FileBuffer->FileName, TRUE); + StatusBarSetStatusString (L"Invalid File Name"); + return EFI_SUCCESS; + } + + break; + } + } + // + // read from disk + // + Status = FileBufferRead (InputBarGetString(), FALSE); + + if (EFI_ERROR (Status)) { + FileBufferRead (MainEditor.FileBuffer->FileName, TRUE); + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Switch a file from ASCII to UNICODE or vise-versa. + + @retval EFI_SUCCESS The switch was ok or a warning was presented. +**/ +EFI_STATUS +MainCommandSwitchFileType ( + VOID + ) +{ + // + // Below is the scenario of File Type command: + // After File Type is executed, file type will be changed to another type + // if file is read-only, can not be modified + // + if (MainEditor.FileBuffer->ReadOnly) { + StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + return EFI_SUCCESS; + } + + if (MainEditor.FileBuffer->FileType == FileTypeUnicode) { + MainEditor.FileBuffer->FileType = FileTypeAscii; + } else { + MainEditor.FileBuffer->FileType = FileTypeUnicode; + } + + MainEditor.FileBuffer->FileModified = TRUE; + + return EFI_SUCCESS; +} + +/** + cut current line to clipboard + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandCutLine ( + VOID + ) +{ + EFI_STATUS Status; + EFI_EDITOR_LINE *Line; + + // + // This command will cut current line ( where cursor is on ) to clip board. + // And cursor will move to the beginning of next line. + // Below is the scenario of Cut Line command: + // 1. IF cursor is on valid line, current line will be cut to clip board. + // IF cursor is not on valid line, an Status String will be prompted : + // "Nothing to Cut". + // + Line = NULL; + Status = FileBufferCutLine (&Line); + if (Status == EFI_NOT_FOUND) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + MainEditor.CutLine = Line; + + return EFI_SUCCESS; +} + +/** + paste line to file buffer. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandPasteLine ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Below is the scenario of Paste Line command: + // 1. IF nothing is on clipboard, a Status String will be prompted : + // "No Line to Paste" and Paste Line command ends. + // IF something is on clipboard, insert it above current line. + // nothing on clipboard + // + if (MainEditor.CutLine == NULL) { + StatusBarSetStatusString (L"No Line to Paste"); + return EFI_SUCCESS; + } + + Status = FileBufferPasteLine (); + + return Status; +} + + +/** + search string in file buffer + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandSearch ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 *Buffer; + BOOLEAN Done; + UINTN Offset; + + // + // Below is the scenario of Search command: + // 1. An Input Bar will be prompted : "Enter Search String:". + // IF user press ESC, Search command ends. + // IF user just press Enter, Search command ends. + // IF user inputs the search string, do Step 2. + // + // 2. IF input search string is found, cursor will move to the first + // occurrence and do Step 3. + // IF input search string is not found, a Status String + // "Search String Not Found" will be prompted and Search command ends. + // + // 3. An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?". + // IF user press ESC, Search command ends. + // IF user press 'y' or 'Y', do Step 2. + // IF user press 'n' or 'N', Search command ends. + // IF user press 'c' or 'C', Search command ends. + // + Status = InputBarSetPrompt (L"Enter Search String: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (40); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + // + // just enter pressed + // + if (StrLen (InputBarGetString()) == 0) { + return EFI_SUCCESS; + } + + Buffer = CatSPrint (NULL, L"%s", InputBarGetString()); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // the first time , search from current position + // + Offset = 0; + do { + // + // since search may be continued to search multiple times + // so we need to backup editor each time + // + MainEditorBackup (); + + Status = FileBufferSearch (Buffer, Offset); + + if (Status == EFI_NOT_FOUND) { + break; + } + // + // Find next + // + Status = InputBarSetPrompt (L"Find Next (Yes/No) ?"); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + FreePool (Buffer); + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + Done = TRUE; + break; + + case L'n': + case L'N': + FreePool (Buffer); + return EFI_SUCCESS; + + } + // + // end of which + // + } + // + // end of while !Done + // for search second, third time, search from current position + strlen + // + Offset = StrLen (Buffer); + + } while (1); + // + // end of do + // + FreePool (Buffer); + StatusBarSetStatusString (L"Search String Not Found"); + + return EFI_SUCCESS; +} + +/** + Search string in file buffer, and replace it with another str. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandSearchReplace ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 *Search; + CHAR16 *Replace; + BOOLEAN Done; + BOOLEAN First; + BOOLEAN ReplaceOption; + UINTN SearchLen; + UINTN ReplaceLen; + BOOLEAN ReplaceAll; + + ReplaceOption = FALSE; + + // + // Below is the scenario of Search/Replace command: + // 1. An Input Bar is prompted : "Enter Search String:". + // IF user press ESC, Search/Replace command ends. + // IF user just press Enter, Search/Replace command ends. + // IF user inputs the search string S, do Step 2. + // + // 2. An Input Bar is prompted: "Replace With:". + // IF user press ESC, Search/Replace command ends. + // IF user inputs the replace string R, do Step 3. + // + // 3. IF input search string is not found, an Status String + // "Search String Not Found" will be prompted + // and Search/Replace command ends + // IF input search string is found, do Step 4. + // + // 4. An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?" + // IF user press 'y' or 'Y', S will be replaced with R and do Step 5 + // IF user press 'n' or 'N', S will not be replaced and do Step 5. + // IF user press 'a' or 'A', all the S from file current position on + // will be replaced with R and Search/Replace command ends. + // IF user press 'c' or 'C' or ESC, Search/Replace command ends. + // + // 5. An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?". + // IF user press ESC, Search/Replace command ends. + // IF user press 'y' or 'Y', do Step 3. + // IF user press 'n' or 'N', Search/Replace command ends. + // IF user press 'c' or 'C', Search/Replace command ends. + // input search string + // + Status = InputBarSetPrompt (L"Enter Search String: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (40); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + // + // if just pressed enter + // + if (StrLen (InputBarGetString()) == 0) { + return EFI_SUCCESS; + } + + Search = CatSPrint (NULL, L"%s", InputBarGetString()); + if (Search == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SearchLen = StrLen (Search); + + // + // input replace string + // + Status = InputBarSetPrompt (L"Replace With: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (40); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + Replace = CatSPrint (NULL, L"%s", InputBarGetString()); + if (Replace == NULL) { + FreePool (Search); + return EFI_OUT_OF_RESOURCES; + } + + ReplaceLen = StrLen (Replace); + + First = TRUE; + ReplaceAll = FALSE; + do { + // + // since search may be continued to search multiple times + // so we need to backup editor each time + // + MainEditorBackup (); + + if (First) { + Status = FileBufferSearch (Search, 0); + } else { + // + // if just replace, so skip this replace string + // if replace string is an empty string, so skip to next character + // + if (ReplaceOption) { + Status = FileBufferSearch (Search, (ReplaceLen == 0) ? 1 : ReplaceLen); + } else { + Status = FileBufferSearch (Search, SearchLen); + } + } + + if (Status == EFI_NOT_FOUND) { + break; + } + // + // replace or not? + // + Status = InputBarSetPrompt (L"Replace (Yes/No/All/Cancel) ?"); + + if (EFI_ERROR (Status)) { + FreePool (Search); + FreePool (Replace); + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + FreePool (Search); + FreePool (Replace); + return Status; + } + + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + FreePool (Search); + FreePool (Replace); + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + Done = TRUE; + ReplaceOption = TRUE; + break; + + case L'n': + case L'N': + Done = TRUE; + ReplaceOption = FALSE; + break; + + case L'a': + case L'A': + Done = TRUE; + ReplaceOption = TRUE; + ReplaceAll = TRUE; + break; + + case L'c': + case L'C': + FreePool (Search); + FreePool (Replace); + return EFI_SUCCESS; + + } + // + // end of which + // + } + // + // end of while !Done + // Decide to Replace + // + if (ReplaceOption) { + // + // file is read-only + // + if (MainEditor.FileBuffer->ReadOnly) { + StatusBarSetStatusString (L"Read Only File Can Not Be Modified"); + return EFI_SUCCESS; + } + // + // replace all + // + if (ReplaceAll) { + Status = FileBufferReplaceAll (Search, Replace, 0); + FreePool (Search); + FreePool (Replace); + return Status; + } + // + // replace + // + Status = FileBufferReplace (Replace, SearchLen); + if (EFI_ERROR (Status)) { + FreePool (Search); + FreePool (Replace); + return Status; + } + } + // + // Find next + // + Status = InputBarSetPrompt (L"Find Next (Yes/No) ?"); + if (EFI_ERROR (Status)) { + FreePool (Search); + FreePool (Replace); + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + FreePool (Search); + FreePool (Replace); + return Status; + } + + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + FreePool (Search); + FreePool (Replace); + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + Done = TRUE; + break; + + case L'n': + case L'N': + FreePool (Search); + FreePool (Replace); + return EFI_SUCCESS; + + } + // + // end of which + // + } + // + // end of while !Done + // + First = FALSE; + + } while (1); + // + // end of do + // + FreePool (Search); + FreePool (Replace); + + StatusBarSetStatusString (L"Search String Not Found"); + + return EFI_SUCCESS; +} + +/** + exit editor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainCommandExit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Below is the scenario of Exit command: + // 1. IF currently opened file is not modified, exit the editor and + // Exit command ends. + // IF currently opened file is modified, do Step 2 + // + // 2. An Input Bar will be prompted: + // "File modified. Save ( Yes/No/Cancel )?" + // IF user press 'y' or 'Y', currently opened file will be saved + // and Editor exits + // IF user press 'n' or 'N', currently opened file will not be saved + // and Editor exits. + // IF user press 'c' or 'C' or ESC, Exit command ends. + // if file has been modified, so will prompt user whether to save the changes + // + if (MainEditor.FileBuffer->FileModified) { + + Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // write file back to disk + // + Status = FileBufferSave (MainEditor.FileBuffer->FileName); + if (!EFI_ERROR (Status)) { + EditorExit = TRUE; + } + + return Status; + + case L'n': + case L'N': + EditorExit = TRUE; + return EFI_SUCCESS; + + case L'c': + case L'C': + return EFI_SUCCESS; + + } + } + } + + EditorExit = TRUE; + return EFI_SUCCESS; + +} + +/** + move cursor to specified lines + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainCommandGotoLine ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Row; + + // + // Below is the scenario of Go To Line command: + // 1. An Input Bar will be prompted : "Go To Line:". + // IF user press ESC, Go To Line command ends. + // IF user just press Enter, cursor remains unchanged. + // IF user inputs line number, do Step 2. + // + // 2. IF input line number is valid, move cursor to the beginning + // of specified line and Go To Line command ends. + // IF input line number is invalid, a Status String will be prompted: + // "No Such Line" and Go To Line command ends. + // + Status = InputBarSetPrompt (L"Go To Line: "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // line number's digit <= 6 + // + Status = InputBarSetStringSize (6); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // press ESC + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + // + // if JUST press enter + // + if (StrLen (InputBarGetString()) == 0) { + return EFI_SUCCESS; + } + + Row = ShellStrToUintn (InputBarGetString()); + + // + // invalid line number + // + if (Row > MainEditor.FileBuffer->NumLines || Row <= 0) { + StatusBarSetStatusString (L"No Such Line"); + return EFI_SUCCESS; + } + // + // move cursor to that line's start + // + FileBufferMovePosition (Row, 1); + + return EFI_SUCCESS; +} + +/** + Save current file to disk, you can save to current file name or + save to another file name. + + @retval EFI_SUCCESS The file was saved correctly. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A file access error occurred. +**/ +EFI_STATUS +MainCommandSaveFile ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 *FileName; + BOOLEAN OldFile; + CHAR16 *Str; + SHELL_FILE_HANDLE FileHandle; + EFI_FILE_INFO *Info; + + // + // This command will save currently opened file to disk. + // You can choose save to another file name or just save to + // current file name. + // Below is the scenario of Save File command: + // ( Suppose the old file name is A ) + // 1. An Input Bar will be prompted: "File To Save: [ old file name]" + // IF user press ESC, Save File command ends . + // IF user press Enter, input file name will be A. + // IF user inputs a new file name B, input file name will be B. + // + // 2. IF input file name is A, go to do Step 3. + // IF input file name is B, go to do Step 4. + // + // 3. IF A is read only, Status Bar will show "Access Denied" and + // Save File commands ends. + // IF A is not read only, save file buffer to disk and remove modified + // flag in Title Bar , then Save File command ends. + // + // 4. IF B does not exist, create this file and save file buffer to it. + // Go to do Step 7. + // IF B exits, do Step 5. + // + // 5.An Input Bar will be prompted: + // "File Exists. Overwrite ( Yes/No/Cancel )?" + // IF user press 'y' or 'Y', do Step 6. + // IF user press 'n' or 'N', Save File commands ends. + // IF user press 'c' or 'C' or ESC, Save File commands ends. + // + // 6. IF B is a read-only file, Status Bar will show "Access Denied" and + // Save File commands ends. + // IF B can be read and write, save file buffer to B. + // + // 7. Update File Name field in Title Bar to B and remove the modified + // flag in Title Bar. + // + Str = CatSPrint (NULL, L"File to Save: [%s]", MainEditor.FileBuffer->FileName); + if (Str == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (StrLen (Str) >= 50) { + // + // replace the long file name with "..." + // + Str[46] = L'.'; + Str[47] = L'.'; + Str[48] = L'.'; + Str[49] = L']'; + Str[50] = CHAR_NULL; + } + + Status = InputBarSetPrompt (Str); + FreePool(Str); + + if (EFI_ERROR (Status)) { + return Status; + } + + + Status = InputBarSetStringSize (100); + if (EFI_ERROR (Status)) { + return Status; + } + // + // get new file name + // + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // if user pressed ESC + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + // + // if just enter pressed, so think save to current file name + // + if (StrLen (InputBarGetString()) == 0) { + FileName = CatSPrint (NULL, L"%s", MainEditor.FileBuffer->FileName); + } else { + FileName = CatSPrint (NULL, L"%s", InputBarGetString()); + } + + if (FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (!IsValidFileName (FileName)) { + StatusBarSetStatusString (L"Invalid File Name"); + FreePool (FileName); + return EFI_SUCCESS; + } + + OldFile = FALSE; + + // + // save to the old file + // + if (StringNoCaseCompare (&FileName, &MainEditor.FileBuffer->FileName) == 0) { + OldFile = TRUE; + } + + if (OldFile) { + // + // if the file is read only, so can not write back to it. + // + if (MainEditor.FileBuffer->ReadOnly == TRUE) { + StatusBarSetStatusString (L"Access Denied"); + FreePool (FileName); + return EFI_SUCCESS; + } + } else { + // + // if the file exists + // + if (ShellFileExists(FileName) != EFI_NOT_FOUND) { + // + // check for read only + // + Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + StatusBarSetStatusString (L"Open Failed"); + FreePool (FileName); + return EFI_SUCCESS; + } + + Info = ShellGetFileInfo(FileHandle); + if (Info == NULL) { + StatusBarSetStatusString (L"Access Denied"); + FreePool (FileName); + return (EFI_SUCCESS); + } + + if (Info->Attribute & EFI_FILE_READ_ONLY) { + StatusBarSetStatusString (L"Access Denied - Read Only"); + FreePool (Info); + FreePool (FileName); + return (EFI_SUCCESS); + } + FreePool (Info); + + // + // ask user whether to overwrite this file + // + Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (FileName); + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (FileName); + return Status; + } + + while (TRUE) { + Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column); + StatusBarSetRefresh(); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + break; + + case L'n': + case L'N': + case L'c': + case L'C': + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } // end switch + } // while (!done) + } // file does exist + } // if old file name same + + // + // save file to disk with specified name + // + FileBufferSetModified(); + Status = FileBufferSave (FileName); + SHELL_FREE_NON_NULL (FileName); + + return Status; +} + +/** + Show help information for the editor. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainCommandDisplayHelp ( + VOID + ) +{ + INT32 CurrentLine; + CHAR16 *InfoString; + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + UINTN EventIndex; + + // + // print helpInfo + // + for (CurrentLine = 0; 0 != MainMenuHelpInfo[CurrentLine]; CurrentLine++) { + InfoString = HiiGetString(gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL); + ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString); + } + + // + // scan for ctrl+w + // + while (TRUE) { + Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex); + if (EFI_ERROR (Status) || (EventIndex != 0)) { + continue; + } + Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData); + if (EFI_ERROR (Status)) { + continue; + } + + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || + (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) { + // + // For consoles that don't support/report shift state, + // CTRL+W is translated to L'W' - L'A' + 1. + // + if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) { + break; + } + } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && + ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) && + ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) { + // + // For consoles that supports/reports shift state, + // make sure that only CONTROL shift key is pressed. + // + if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) { + break; + } + } + } + // + // update screen with file buffer's info + // + FileBufferRestorePosition (); + FileBufferNeedRefresh = TRUE; + FileBufferOnlyLineNeedRefresh = FALSE; + FileBufferRefresh (); + + return EFI_SUCCESS; +} + +EFI_EDITOR_COLOR_ATTRIBUTES OriginalColors; +INTN OriginalMode; + + +// +// basic initialization for MainEditor +// +EFI_EDITOR_GLOBAL_EDITOR MainEditorConst = { + &FileBuffer, + { + {0, 0} + }, + { + 0, + 0 + }, + NULL, + NULL, + FALSE, + NULL +}; + +/** + The initialization function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainEditorInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + + // + // basic initialization + // + CopyMem (&MainEditor, &MainEditorConst, sizeof (MainEditor)); + + // + // set screen attributes + // + MainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff; + + MainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4); + OriginalColors = MainEditor.ColorAttributes.Colors; + + OriginalMode = gST->ConOut->Mode->Mode; + + // + // query screen size + // + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &(MainEditor.ScreenSize.Column), + &(MainEditor.ScreenSize.Row) + ); + + // + // Find TextInEx in System Table ConsoleInHandle + // Per UEFI Spec, TextInEx is required for a console capable platform. + // + Status = gBS->HandleProtocol ( + gST->ConsoleInHandle, + &gEfiSimpleTextInputExProtocolGuid, + (VOID**)&MainEditor.TextInputEx + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Find mouse in System Table ConsoleInHandle + // + Status = gBS->HandleProtocol ( + gST->ConsoleInHandle, + &gEfiSimplePointerProtocolGuid, + (VOID**)&MainEditor.MouseInterface + ); + if (EFI_ERROR (Status)) { + // + // If there is no Simple Pointer Protocol on System Table + // + HandleBuffer = NULL; + MainEditor.MouseInterface = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimplePointerProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status) && HandleCount > 0) { + // + // Try to find the first available mouse device + // + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiSimplePointerProtocolGuid, + (VOID**)&MainEditor.MouseInterface + ); + if (!EFI_ERROR (Status)) { + break; + } + } + } + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + } + + if (!EFI_ERROR (Status) && MainEditor.MouseInterface != NULL) { + MainEditor.MouseAccumulatorX = 0; + MainEditor.MouseAccumulatorY = 0; + MainEditor.MouseSupported = TRUE; + } + + // + // below will call the five components' init function + // + Status = MainTitleBarInit (L"UEFI EDIT"); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_TITLEBAR), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + Status = ControlHotKeyInit (MainControlBasedMenuFunctions); + Status = MenuBarInit (MainMenuItems); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_MAINMENU), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + Status = StatusBarInit (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_STATUSBAR), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + InputBarInit (MainEditor.TextInputEx); + + Status = FileBufferInit (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + // + // clear whole screen and enable cursor + // + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + // + // initialize EditorFirst and EditorExit + // + EditorFirst = TRUE; + EditorExit = FALSE; + EditorMouseAction = FALSE; + + return EFI_SUCCESS; +} + +/** + The cleanup function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainEditorCleanup ( + VOID + ) +{ + EFI_STATUS Status; + + // + // call the five components' cleanup function + // if error, do not exit + // just print some warning + // + MainTitleBarCleanup(); + StatusBarCleanup(); + InputBarCleanup(); + MenuBarCleanup (); + + Status = FileBufferCleanup (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP), gShellDebug1HiiHandle); + } + // + // restore old mode + // + if (OriginalMode != gST->ConOut->Mode->Mode) { + gST->ConOut->SetMode (gST->ConOut, OriginalMode); + } + // + // restore old screen color + // + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR (OriginalColors.Foreground, OriginalColors.Background) + ); + + gST->ConOut->ClearScreen (gST->ConOut); + + return EFI_SUCCESS; +} + +/** + Refresh the main editor component. +**/ +VOID +MainEditorRefresh ( + VOID + ) +{ + // + // The Stall value is from experience. NOT from spec. avoids 'flicker' + // + gBS->Stall (50); + + // + // call the components refresh function + // + if (EditorFirst + || StrCmp (FileBufferBackupVar.FileName, FileBuffer.FileName) != 0 + || FileBufferBackupVar.FileType != FileBuffer.FileType + || FileBufferBackupVar.FileModified != FileBuffer.FileModified + || FileBufferBackupVar.ReadOnly != FileBuffer.ReadOnly) { + + MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0); + FileBufferRestorePosition (); + } + + if (EditorFirst + || FileBufferBackupVar.FilePosition.Row != FileBuffer.FilePosition.Row + || FileBufferBackupVar.FilePosition.Column != FileBuffer.FilePosition.Column + || FileBufferBackupVar.ModeInsert != FileBuffer.ModeInsert + || StatusBarGetRefresh()) { + + StatusBarRefresh (EditorFirst, MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column, MainEditor.FileBuffer->FilePosition.Row, MainEditor.FileBuffer->FilePosition.Column, MainEditor.FileBuffer->ModeInsert); + FileBufferRestorePosition (); + } + + if (EditorFirst) { + FileBufferRestorePosition (); + } + + FileBufferRefresh (); + + // + // EditorFirst is now set to FALSE + // + EditorFirst = FALSE; +} + +/** + Get's the resultant location of the cursor based on the relative movement of the Mouse. + + @param[in] GuidX The relative mouse movement. + + @return The X location of the mouse. +**/ +INT32 +GetTextX ( + IN INT32 GuidX + ) +{ + INT32 Gap; + + MainEditor.MouseAccumulatorX += GuidX; + Gap = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX); + MainEditor.MouseAccumulatorX = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX); + MainEditor.MouseAccumulatorX = MainEditor.MouseAccumulatorX / (INT32) MainEditor.ScreenSize.Column; + return Gap; +} + +/** + Get's the resultant location of the cursor based on the relative movement of the Mouse. + + @param[in] GuidY The relative mouse movement. + + @return The Y location of the mouse. +**/ +INT32 +GetTextY ( + IN INT32 GuidY + ) +{ + INT32 Gap; + + MainEditor.MouseAccumulatorY += GuidY; + Gap = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY); + MainEditor.MouseAccumulatorY = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY); + MainEditor.MouseAccumulatorY = MainEditor.MouseAccumulatorY / (INT32) MainEditor.ScreenSize.Row; + + return Gap; +} + +/** + Support mouse movement. Move the cursor. + + @param[in] MouseState The current mouse state. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_NOT_FOUND There was no mouse support found. +**/ +EFI_STATUS +MainEditorHandleMouseInput ( + IN EFI_SIMPLE_POINTER_STATE MouseState + ) +{ + + INT32 TextX; + INT32 TextY; + UINTN FRow; + UINTN FCol; + + LIST_ENTRY *Link; + EFI_EDITOR_LINE *Line; + + UINTN Index; + BOOLEAN Action; + + // + // mouse action means: + // mouse movement + // mouse left button + // + Action = FALSE; + + // + // have mouse movement + // + if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) { + // + // handle + // + TextX = GetTextX (MouseState.RelativeMovementX); + TextY = GetTextY (MouseState.RelativeMovementY); + + FileBufferAdjustMousePosition (TextX, TextY); + + Action = TRUE; + + } + + // + // if left button pushed down + // + if (MouseState.LeftButton) { + + FCol = MainEditor.FileBuffer->MousePosition.Column - 1 + 1; + + FRow = MainEditor.FileBuffer->FilePosition.Row + + MainEditor.FileBuffer->MousePosition.Row - + MainEditor.FileBuffer->DisplayPosition.Row; + + // + // beyond the file line length + // + if (MainEditor.FileBuffer->NumLines < FRow) { + FRow = MainEditor.FileBuffer->NumLines; + } + + Link = MainEditor.FileBuffer->ListHead->ForwardLink; + for (Index = 0; Index < FRow - 1; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE); + + // + // beyond the line's column length + // + if (FCol > Line->Size + 1) { + FCol = Line->Size + 1; + } + + FileBufferMovePosition (FRow, FCol); + + MainEditor.FileBuffer->MousePosition.Row = MainEditor.FileBuffer->DisplayPosition.Row; + + MainEditor.FileBuffer->MousePosition.Column = MainEditor.FileBuffer->DisplayPosition.Column; + + Action = TRUE; + } + // + // mouse has action + // + if (Action) { + return EFI_SUCCESS; + } + + // + // no mouse action + // + return EFI_NOT_FOUND; +} + +/** + Handle user key input. This routes to other functions for the actions. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainEditorKeyInput ( + VOID + ) +{ + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + EFI_SIMPLE_POINTER_STATE MouseState; + BOOLEAN NoShiftState; + + do { + + Status = EFI_SUCCESS; + EditorMouseAction = FALSE; + + // + // backup some key elements, so that can aVOID some refresh work + // + MainEditorBackup (); + + // + // change priority of checking mouse/keyboard activity dynamically + // so prevent starvation of keyboard. + // if last time, mouse moves then this time check keyboard + // + if (MainEditor.MouseSupported) { + Status = MainEditor.MouseInterface->GetState ( + MainEditor.MouseInterface, + &MouseState + ); + if (!EFI_ERROR (Status)) { + + Status = MainEditorHandleMouseInput (MouseState); + + if (!EFI_ERROR (Status)) { + EditorMouseAction = TRUE; + FileBufferMouseNeedRefresh = TRUE; + } else if (Status == EFI_LOAD_ERROR) { + StatusBarSetStatusString (L"Invalid Mouse Movement "); + } + } + } + + // + // CheckEvent() returns Success when non-partial key is pressed. + // + Status = gBS->CheckEvent (MainEditor.TextInputEx->WaitForKeyEx); + if (!EFI_ERROR (Status)) { + Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData); + if (!EFI_ERROR (Status)) { + // + // dispatch to different components' key handling function + // so not everywhere has to set this variable + // + FileBufferMouseNeedRefresh = TRUE; + // + // clear previous status string + // + StatusBarSetRefresh(); + // + // NoShiftState: TRUE when no shift key is pressed. + // + NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID); + // + // dispatch to different components' key handling function + // + if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&KeyData)) { + Status = EFI_SUCCESS; + } else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) { + Status = FileBufferHandleInput (&KeyData.Key); + } else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) { + Status = MenuBarDispatchFunctionKey (&KeyData.Key); + } else { + StatusBarSetStatusString (L"Unknown Command"); + FileBufferMouseNeedRefresh = FALSE; + } + + if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) { + // + // not already has some error status + // + if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) { + StatusBarSetStatusString (L"Disk Error. Try Again"); + } + } + + } + } + // + // after handling, refresh editor + // + MainEditorRefresh (); + + } while (Status != EFI_OUT_OF_RESOURCES && !EditorExit); + + return Status; +} + +/** + Set clipboard + + @param[in] Line A pointer to the line to be set to clipboard + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainEditorSetCutLine ( + EFI_EDITOR_LINE *Line + ) +{ + if (Line == NULL) { + return EFI_SUCCESS; + } + + if (MainEditor.CutLine != NULL) { + // + // free the old clipboard + // + LineFree (MainEditor.CutLine); + } + // + // duplicate the line to clipboard + // + MainEditor.CutLine = LineDup (Line); + if (MainEditor.CutLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Backup function for MainEditor + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainEditorBackup ( + VOID + ) +{ + FileBufferBackup (); + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.h new file mode 100644 index 00000000..8ee024c8 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.h @@ -0,0 +1,66 @@ +/** @file + Declares editor interface functions. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_EDITOR_H_ +#define _LIB_EDITOR_H_ + +#include "TextEditorTypes.h" + +/** + The initialization function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainEditorInit ( + VOID + ); + +/** + The cleanup function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +MainEditorCleanup ( + VOID + ); + +/** + Refresh the main editor component. +**/ +VOID +MainEditorRefresh ( + VOID + ); + +/** + Handle user key input. This routes to other functions for the actions. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainEditorKeyInput ( + VOID + ); + +/** + Backup function for MainEditor + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainEditorBackup ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.c new file mode 100644 index 00000000..e98e520c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.c @@ -0,0 +1,84 @@ +/** @file + Implementation of various string and line routines. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "TextEditor.h" +#include "Misc.h" + +/** + Duplicate a EFI_EDITOR_LINE structure. + + @param Src The line structure to copy from. + + @retval NULL A memory allocation failed. + @return a pointer to the newly allcoated line. +**/ +EFI_EDITOR_LINE * +LineDup ( + IN EFI_EDITOR_LINE *Src + ) +{ + EFI_EDITOR_LINE *Dest; + + // + // allocate for the line structure + // + Dest = AllocateZeroPool (sizeof (EFI_EDITOR_LINE)); + if (Dest == NULL) { + return NULL; + } + // + // allocate and set the line buffer + // + Dest->Buffer = CatSPrint (NULL, L"%s", Src->Buffer); + if (Dest->Buffer == NULL) { + FreePool (Dest); + return NULL; + } + + // + // set the other structure members + // + Dest->Signature = LINE_LIST_SIGNATURE; + Dest->Size = Src->Size; + Dest->TotalSize = Dest->Size; + Dest->Type = Src->Type; + Dest->Link = Src->Link; + + return Dest; +} + +/** + Free a EFI_EDITOR_LINE structure. + + @param Src The line structure to free. +**/ +VOID +LineFree ( + IN EFI_EDITOR_LINE *Src + ) +{ + if (Src == NULL) { + return ; + } + // + // free the line buffer and then the line structure itself + // + SHELL_FREE_NON_NULL (Src->Buffer); + SHELL_FREE_NON_NULL (Src); + +} + + + + + + + + + + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.h new file mode 100644 index 00000000..ba25e4e1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/Misc.h @@ -0,0 +1,44 @@ +/** @file + Declares generic editor helper functions. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MISC_H_ +#define _LIB_MISC_H_ + +#include "TextEditorTypes.h" + + + +/** + Free a EFI_EDITOR_LINE structure. + + @param Src The line structure to free. +**/ +VOID +LineFree ( + IN EFI_EDITOR_LINE *Src + ); + +/** + Duplicate a EFI_EDITOR_LINE structure. + + @param Src The line structure to copy from. + + @retval NULL A memory allocation failed. + @return a pointer to the newly allcoated line. +**/ +EFI_EDITOR_LINE * +LineDup ( + IN EFI_EDITOR_LINE *Src + ); + + + + + + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditStrings.uni b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditStrings.uni new file mode 100644 index 00000000..f38221df --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditStrings.uni @@ -0,0 +1,69 @@ +// /**
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Abstract:
+//
+// Additional string definitions for UEFI Shell 2.0 Debug1 profile Edit command
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "english"
+
+#string STR_EDIT_LIBEDITOR_TITLEBAR #language en-US "%EMainEditor init failed on TitleBar init\r\n%N"
+#string STR_EDIT_LIBEDITOR_MAINMENU #language en-US "%EMainEditor init was not successful on MainMenu init\r\n%N"
+#string STR_EDIT_LIBEDITOR_STATUSBAR #language en-US "%EMainEditor init was not successful on StatusBar init\r\n%N"
+#string STR_EDIT_LIBEDITOR_INPUTBAR #language en-US "%EMainEditor init was not successful on InputBar init\r\n%N"
+#string STR_EDIT_LIBEDITOR_FILEBUFFER #language en-US "%EMainEditor init was not successful on FileBuffer init\r\n%N"
+#string STR_EDIT_LIBEDITOR_TITLEBAR_CLEANUP #language en-US "TitleBar cleanup was not successful\r\n"
+#string STR_EDIT_LIBEDITOR_MENUBAR_CLEANUP #language en-US "MenuBar cleanup was not successful\r\n"
+#string STR_EDIT_LIBEDITOR_STATUSBAR_CLEANUP #language en-US "StatusBar cleanup was not successful\r\n"
+#string STR_EDIT_LIBEDITOR_INPUTBAR_CLEANUP #language en-US "InputBar cleanup was not successful\r\n"
+#string STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP #language en-US "FileBuffer cleanup was not successful\r\n"
+#string STR_EDIT_LIBEDITOR_MAINEDITOR_INIT #language en-US "%EMainEditor init was not succesful on TitleBar init\r\n%N"
+#string STR_EDIT_LIBINPUTBAR_MAININPUTBAR #language en-US "%s"
+#string STR_EDIT_LIBMENUBAR_OPEN_FILE #language en-US "Open File"
+#string STR_EDIT_LIBMENUBAR_SAVE_FILE #language en-US "Save File"
+#string STR_EDIT_LIBMENUBAR_EXIT #language en-US "Exit"
+#string STR_EDIT_LIBMENUBAR_CUT_LINE #language en-US "Cut Line"
+#string STR_EDIT_LIBMENUBAR_PASTE_LINE #language en-US "Paste Line"
+#string STR_EDIT_LIBMENUBAR_GO_TO_LINE #language en-US "Go To Line"
+#string STR_EDIT_LIBMENUBAR_SEARCH #language en-US "Search"
+#string STR_EDIT_LIBMENUBAR_SEARCH_REPLACE #language en-US "Search/Replace"
+#string STR_EDIT_LIBMENUBAR_FILE_TYPE #language en-US "File Type"
+#string STR_EDIT_LIBMENUBAR_F1 #language en-US "F1"
+#string STR_EDIT_LIBMENUBAR_F2 #language en-US "F2"
+#string STR_EDIT_LIBMENUBAR_F3 #language en-US "F3"
+#string STR_EDIT_LIBMENUBAR_F4 #language en-US "F4"
+#string STR_EDIT_LIBMENUBAR_F5 #language en-US "F5"
+#string STR_EDIT_LIBMENUBAR_F6 #language en-US "F6"
+#string STR_EDIT_LIBMENUBAR_F7 #language en-US "F7"
+#string STR_EDIT_LIBMENUBAR_F8 #language en-US "F8"
+#string STR_EDIT_LIBMENUBAR_F9 #language en-US "F9"
+#string STR_EDIT_LIBMENUBAR_F10 #language en-US "F10"
+#string STR_EDIT_LIBMENUBAR_F11 #language en-US "F11"
+#string STR_EDIT_LIBMENUBAR_F12 #language en-US "F12"
+#string STR_EDIT_LIBMENUBAR_CTRL_E #language en-US "Ctrl+E"
+#string STR_EDIT_LIBMENUBAR_CTRL_W #language en-US "Ctrl+W"
+#string STR_EDIT_HELP_TITLE #language en-US "Help \n"
+#string STR_EDIT_HELP_BLANK #language en-US " \n"
+#string STR_EDIT_HELP_LIST_TITLE #language en-US "Control Key Function Key Command \n"
+#string STR_EDIT_HELP_DIV #language en-US "----------- ------------ ----------------- \n"
+#string STR_EDIT_HELP_GO_TO_LINE #language en-US "Ctrl-G F1 Go To Line \n"
+#string STR_EDIT_HELP_SAVE_FILE #language en-US "Ctrl-S F2 Save File \n"
+#string STR_EDIT_HELP_EXIT #language en-US "Ctrl-Q F3 Exit \n"
+#string STR_EDIT_HELP_SEARCH #language en-US "Ctrl-F F4 Search \n"
+#string STR_EDIT_HELP_SEARCH_REPLACE #language en-US "Ctrl-R F5 Search/Replace \n"
+#string STR_EDIT_HELP_CUT_LINE #language en-US "Ctrl-K F6 Cut Line \n"
+#string STR_EDIT_HELP_PASTE_LINE #language en-US "Ctrl-U F7 Paste Line \n"
+#string STR_EDIT_HELP_OPEN_FILE #language en-US "Ctrl-O F8 Open File \n"
+#string STR_EDIT_HELP_FILE_TYPE #language en-US "Ctrl-T F9 File Type \n"
+#string STR_EDIT_HELP_EXIT_HELP #language en-US "Use Ctrl-W to exit this help \n"
+#string STR_EDIT_MAIN_INVALID_FILE_NAME #language en-US "%Hedit%N: Invalid File Name\r\n"
+#string STR_EDIT_MAIN_INIT_FAILED #language en-US "%Hedit%N: Initialization was not successful\r\n"
+#string STR_EDIT_MAIN_BUFFER #language en-US "%Hedit%N: %s\r\n"
+#string STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR #language en-US "%Hedit%N: Unknown Editor Error\r\n"
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditor.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditor.h new file mode 100644 index 00000000..c912abb4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditor.h @@ -0,0 +1,26 @@ +/** @file + Main include file for Edit shell Debug1 function. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_EDIT_H_ +#define _EFI_EDIT_H_ + +#include "TextEditorTypes.h" + +#include "MainTextEditor.h" +#include "FileBuffer.h" +#include "EditTitleBar.h" +#include "EditStatusBar.h" +#include "EditInputBar.h" +#include "EditMenuBar.h" +#include "Misc.h" + +extern EFI_EDITOR_GLOBAL_EDITOR MainEditor; +extern BOOLEAN EditorFirst; +extern BOOLEAN EditorExit; + +#endif // _EFI_EDIT_H_ diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h new file mode 100644 index 00000000..49e6e218 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h @@ -0,0 +1,97 @@ +/** @file + Declares editor types. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EDITOR_TYPE_H_ +#define _EDITOR_TYPE_H_ + +#include "UefiShellDebug1CommandsLib.h" +#include "EditTitleBar.h" +#include "EditMenuBar.h" + +#define MIN_POOL_SIZE 125 +#define MAX_STRING_LENGTH 127 + +typedef struct { + UINTN Row; + UINTN Column; +} EFI_EDITOR_POSITION; + +typedef +EFI_STATUS +(*EFI_MENU_ITEM_FUNCTION) ( + VOID + ); + +typedef enum { + NewLineTypeDefault, + NewLineTypeLineFeed, + NewLineTypeCarriageReturn, + NewLineTypeCarriageReturnLineFeed, + NewLineTypeLineFeedCarriageReturn, + NewLineTypeUnknown +} EE_NEWLINE_TYPE; + +#define LINE_LIST_SIGNATURE SIGNATURE_32 ('e', 'e', 'l', 'l') +typedef struct _EFI_EDITOR_LINE { + UINTN Signature; + CHAR16 *Buffer; + UINTN Size; // unit is Unicode + UINTN TotalSize; // unit is Unicode, exclude CHAR_NULL + EE_NEWLINE_TYPE Type; + LIST_ENTRY Link; +} EFI_EDITOR_LINE; + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 4; +} EFI_EDITOR_COLOR_ATTRIBUTES; + +typedef union { + EFI_EDITOR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} EFI_EDITOR_COLOR_UNION; + +typedef struct { + UINTN Columns; + UINTN Rows; +} EFI_EDITOR_TEXT_MODE; + +typedef struct { + CHAR16 *FileName; // file name current edited in editor + EDIT_FILE_TYPE FileType; // Unicode file or ASCII file + LIST_ENTRY *ListHead; // list head of lines + EFI_EDITOR_LINE *Lines; // lines of current file + UINTN NumLines; // total line numbers + EFI_EDITOR_POSITION DisplayPosition; // cursor position in screen + EFI_EDITOR_POSITION FilePosition; // cursor position in file + EFI_EDITOR_POSITION MousePosition; // mouse position in screen + // file position of first byte displayed on screen + // + EFI_EDITOR_POSITION LowVisibleRange; + + BOOLEAN FileModified; // file is modified or not + BOOLEAN ModeInsert; // input mode INS or OVR + BOOLEAN ReadOnly; // file is read-only or not + EFI_EDITOR_LINE *CurrentLine; // current line cursor is at +} EFI_EDITOR_FILE_BUFFER; + +typedef struct { + EFI_EDITOR_FILE_BUFFER *FileBuffer; + + EFI_EDITOR_COLOR_UNION ColorAttributes; + EFI_EDITOR_POSITION ScreenSize; // row number and column number + EFI_EDITOR_LINE *CutLine; // clip board + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; + BOOLEAN MouseSupported; + EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; + INT32 MouseAccumulatorX; + INT32 MouseAccumulatorY; + +} EFI_EDITOR_GLOBAL_EDITOR; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c new file mode 100644 index 00000000..ff683e45 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c @@ -0,0 +1,324 @@ +/** @file + Implements inputbar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "EditInputBar.h" +#include "UefiShellDebug1CommandsLib.h" + +CHAR16 *mPrompt; // Input bar mPrompt string. +CHAR16 *mReturnString; // The returned string. +UINTN StringSize; // Size of mReturnString space size. +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mTextInEx; + +/** + Initialize the input bar. + + @param[in] TextInEx Pointer to SimpleTextInEx instance in System Table. +**/ +VOID +InputBarInit ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx + ) +{ + mPrompt = NULL; + mReturnString = NULL; + StringSize = 0; + mTextInEx = TextInEx; +} + +/** + Cleanup function for input bar. +**/ +VOID +InputBarCleanup ( + VOID + ) +{ + // + // free input bar's prompt and input string + // + SHELL_FREE_NON_NULL (mPrompt); + SHELL_FREE_NON_NULL (mReturnString); + mPrompt = NULL; + mReturnString = NULL; +} + +/** + Display the prompt. + Do the requesting of input. + + @param[in] LastColumn The last printable column. + @param[in] LastRow The last printable row. +**/ +VOID +InputBarPrintInput ( + IN UINTN LastColumn, + IN UINTN LastRow + ) +{ + UINTN Limit; + UINTN Size; + CHAR16 *Buffer; + UINTN Index; + UINTN mPromptLen; + + mPromptLen = StrLen (mPrompt); + Limit = LastColumn - mPromptLen - 1; + Size = StrLen (mReturnString); + + // + // check whether the mPrompt length and input length will + // exceed limit + // + if (Size <= Limit) { + Buffer = mReturnString; + } else { + Buffer = mReturnString + Size - Limit; + } + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + ShellPrintEx (((INT32)mPromptLen), ((INT32)LastRow) - 1, L"%s", Buffer); + Size = StrLen (Buffer); + + // + // print " " after mPrompt + // + for (Index = Size; Index < Limit; Index++) { + ShellPrintEx ((INT32)(mPromptLen + Size), ((INT32)LastRow) - 1, L" "); + } + + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + gST->ConOut->SetCursorPosition (gST->ConOut, Size + mPromptLen, LastRow - 1); +} + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 3; +} INPUT_BAR_COLOR_ATTRIBUTES; + +typedef union { + INPUT_BAR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} INPUT_BAR_COLOR_UNION; + + +/** + The refresh function for InputBar, it will wait for user input + + @param[in] LastRow The last printable row. + @param[in] LastColumn The last printable column. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +InputBarRefresh ( + UINTN LastRow, + UINTN LastColumn + ) +{ + INPUT_BAR_COLOR_UNION Orig; + INPUT_BAR_COLOR_UNION New; + EFI_KEY_DATA KeyData; + UINTN Size; + EFI_STATUS Status; + BOOLEAN NoDisplay; + UINTN EventIndex; + UINTN CursorRow; + UINTN CursorCol; + + // + // variable initialization + // + Size = 0; + Status = EFI_SUCCESS; + + // + // back up the old screen attributes + // + CursorCol = gST->ConOut->Mode->CursorColumn; + CursorRow = gST->ConOut->Mode->CursorRow; + Orig.Data = gST->ConOut->Mode->Attribute; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + + // + // clear input bar + // + EditorClearLine (LastRow , LastColumn, LastRow); + + gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt); + + // + // this is a selection mPrompt, cursor will stay in edit area + // actually this is for search , search/replace + // + if (StrStr (mPrompt, L"Yes/No")) { + NoDisplay = TRUE; + gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow); + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } else { + NoDisplay = FALSE; + } + // + // wait for user input + // + for (;;) { + Status = gBS->WaitForEvent (1, &mTextInEx->WaitForKeyEx, &EventIndex); + if (EFI_ERROR (Status) || (EventIndex != 0)) { + continue; + } + Status = mTextInEx->ReadKeyStrokeEx (mTextInEx, &KeyData); + if (EFI_ERROR (Status)) { + continue; + } + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && + (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID)) { + // + // Shift key pressed. + // + continue; + } + // + // pressed ESC + // + if (KeyData.Key.ScanCode == SCAN_ESC) { + Size = 0; + Status = EFI_NOT_READY; + break; + } + // + // return pressed + // + if (KeyData.Key.UnicodeChar == CHAR_LINEFEED || KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + break; + } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) { + // + // backspace + // + if (Size > 0) { + Size--; + mReturnString[Size] = CHAR_NULL; + if (!NoDisplay) { + + InputBarPrintInput (LastColumn, LastRow); + + } + } + } else if (KeyData.Key.UnicodeChar <= 127 && KeyData.Key.UnicodeChar >= 32) { + // + // VALID ASCII char pressed + // + mReturnString[Size] = KeyData.Key.UnicodeChar; + + // + // should be less than specified length + // + if (Size >= StringSize) { + continue; + } + + Size++; + + mReturnString[Size] = CHAR_NULL; + + if (!NoDisplay) { + + InputBarPrintInput (LastColumn, LastRow); + + } else { + // + // if just choose yes/no + // + break; + } + + } + } + + mReturnString[Size] = CHAR_NULL; + + + // + // restore screen attributes + // + gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow); + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + + return Status; +} + +/** + SetPrompt and wait for input. + + @param[in] Str The prompt string. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetPrompt ( + IN CONST CHAR16 *Str + ) +{ + // + // FREE the old mPrompt string + // + SHELL_FREE_NON_NULL (mPrompt); + + mPrompt = CatSPrint (NULL, L"%s ", Str); + if (mPrompt == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Set the size of the string in characters. + + @param[in] Size The max number of characters to accept. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetStringSize ( + UINTN Size + ) +{ + // + // free the old ReturnStirng + // + SHELL_FREE_NON_NULL (mReturnString); + + StringSize = Size; + mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof(mReturnString[0])); + if (mReturnString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Function to retrieve the input from the user. + + @retval NULL No input has been received. + @return The string that was input. +**/ +CONST CHAR16* +InputBarGetString ( + VOID + ) +{ + return (mReturnString); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h new file mode 100644 index 00000000..c40aa59a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h @@ -0,0 +1,81 @@ +/** @file + Declares imputbar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_INPUT_BAR_H_ +#define _LIB_INPUT_BAR_H_ + +/** + Initialize the input bar. + + @param[in] TextInEx Pointer to SimpleTextInEx instance in System Table. +**/ +VOID +InputBarInit ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx + ); + +/** + Cleanup function for input bar. +**/ +VOID +InputBarCleanup ( + VOID + ); + +/** + The refresh function for InputBar, it will wait for user input + + @param[in] LastRow The last printable row. + @param[in] LastColumn The last printable column. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +InputBarRefresh ( + UINTN LastRow, + UINTN LastColumn + ); + +/** + SetPrompt and wait for input. + + @param[in] Str The prompt string. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetPrompt ( + IN CONST CHAR16 *Str + ); + +/** + Set the size of the string in characters. + + @param[in] Size The max number of characters to accept. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetStringSize ( + UINTN Size + ); + +/** + Function to retrieve the input from the user. + + @retval NULL No input has been received. + @return The string that was input. +**/ +CONST CHAR16* +InputBarGetString ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c new file mode 100644 index 00000000..23acfb42 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c @@ -0,0 +1,210 @@ +/** @file + implements menubar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "EditMenuBar.h" +#include "UefiShellDebug1CommandsLib.h" +#include "EditStatusBar.h" + +EDITOR_MENU_ITEM *MenuItems; +MENU_ITEM_FUNCTION *ControlBasedMenuFunctions; +UINTN NumItems; + +/** + Cleanup function for a menu bar. frees all allocated memory. +**/ +VOID +MenuBarCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL(MenuItems); +} + +/** + Initialize the menu bar with the specified items. + + @param[in] Items The items to display and their functions. + + @retval EFI_SUCCESS The initialization was correct. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MenuBarInit ( + IN CONST EDITOR_MENU_ITEM *Items + ) +{ + CONST EDITOR_MENU_ITEM *ItemsWalker; + + for (NumItems = 0, ItemsWalker = Items ; ItemsWalker != NULL && ItemsWalker->Function != NULL ; ItemsWalker++,NumItems++); + + MenuItems = AllocateZeroPool((NumItems+1) * sizeof(EDITOR_MENU_ITEM)); + if (MenuItems == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem(MenuItems, Items, (NumItems+1) * sizeof(EDITOR_MENU_ITEM)); + return EFI_SUCCESS; +} + +/** + Initialize the control hot-key with the specified items. + + @param[in] Items The hot-key functions. + + @retval EFI_SUCCESS The initialization was correct. +**/ +EFI_STATUS +ControlHotKeyInit ( + IN MENU_ITEM_FUNCTION *Items + ) +{ + ControlBasedMenuFunctions = Items; + return EFI_SUCCESS; +} +/** + Refresh function for the menu bar. + + @param[in] LastRow The last printable row. + @param[in] LastCol The last printable column. + + @retval EFI_SUCCESS The refresh was successful. +**/ +EFI_STATUS +MenuBarRefresh ( + IN CONST UINTN LastRow, + IN CONST UINTN LastCol + ) +{ + EDITOR_MENU_ITEM *Item; + UINTN Col; + UINTN Row; + UINTN Width; + CHAR16 *NameString; + CHAR16 *FunctionKeyString; + + // + // variable initialization + // + Col = 1; + Row = (LastRow - 2); + + // + // clear menu bar rows + // + EditorClearLine (LastRow - 2, LastCol, LastRow); + EditorClearLine (LastRow - 1, LastCol, LastRow); + EditorClearLine (LastRow , LastCol, LastRow); + + + // + // print out the menu items + // + for (Item = MenuItems; Item != NULL && Item->Function != NULL; Item++) { + + + NameString = HiiGetString(gShellDebug1HiiHandle, Item->NameToken, NULL); + + + Width = MAX ((StrLen (NameString) + 6), 20); + if (((Col + Width) > LastCol)) { + Row++; + Col = 1; + } + + FunctionKeyString = HiiGetString(gShellDebug1HiiHandle, Item->FunctionKeyToken, NULL); + + ShellPrintEx ((INT32)(Col) - 1, (INT32)(Row) - 1, L"%E%s%N %H%s%N ", FunctionKeyString, NameString); + + FreePool (NameString); + FreePool (FunctionKeyString); + Col += Width; + } + + return EFI_SUCCESS; +} + +/** + Function to dispatch the correct function based on a function key (F1...) + + @param[in] Key The pressed key. + + @retval EFI_NOT_FOUND The key was not a valid function key + (an error was sent to the status bar). + @return The return value from the called dispatch function. +**/ +EFI_STATUS +MenuBarDispatchFunctionKey ( + IN CONST EFI_INPUT_KEY *Key + ) +{ + UINTN Index; + + Index = Key->ScanCode - SCAN_F1; + + // + // check whether in range + // + if (Index > (NumItems - 1)) { + StatusBarSetStatusString (L"Unknown Command"); + return EFI_SUCCESS; + } + + return (MenuItems[Index].Function ()); +} + +/** + Function to dispatch the correct function based on a control-based key (ctrl+o...) + + @param[in] KeyData The pressed key. + + @retval EFI_NOT_FOUND The key was not a valid control-based key + (an error was sent to the status bar). + @return EFI_SUCCESS. +**/ +EFI_STATUS +MenuBarDispatchControlHotKey ( + IN CONST EFI_KEY_DATA *KeyData + ) +{ + UINT16 ControlIndex; + + // + // Set to invalid value first. + // + ControlIndex = MAX_UINT16; + + if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || + (KeyData->KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) { + // + // For consoles that don't support/report shift state, + // Ctrl+A is translated to 1 (UnicodeChar). + // + ControlIndex = KeyData->Key.UnicodeChar; + } else if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && + ((KeyData->KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) != 0) && + ((KeyData->KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) == 0)) { + // + // For consoles that supports/reports shift state, + // make sure only CONTROL is pressed. + // + if ((KeyData->Key.UnicodeChar >= L'A') && (KeyData->Key.UnicodeChar <= L'Z')) { + ControlIndex = KeyData->Key.UnicodeChar - L'A' + 1; + } else if ((KeyData->Key.UnicodeChar >= L'a') && (KeyData->Key.UnicodeChar <= L'z')) { + ControlIndex = KeyData->Key.UnicodeChar - L'a' + 1; + } + } + if ((SCAN_CONTROL_Z < ControlIndex) + ||(NULL == ControlBasedMenuFunctions[ControlIndex])) + { + return EFI_NOT_FOUND; + } + + ControlBasedMenuFunctions[ControlIndex](); + return EFI_SUCCESS; +} + + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h new file mode 100644 index 00000000..2653291d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h @@ -0,0 +1,113 @@ +/** @file + Declares menubar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MENU_BAR_H_ +#define _LIB_MENU_BAR_H_ + +#define SCAN_CONTROL_E 5 +#define SCAN_CONTROL_F 6 +#define SCAN_CONTROL_G 7 +#define SCAN_CONTROL_K 11 +#define SCAN_CONTROL_O 15 +#define SCAN_CONTROL_Q 17 +#define SCAN_CONTROL_R 18 +#define SCAN_CONTROL_S 19 +#define SCAN_CONTROL_T 20 +#define SCAN_CONTROL_U 21 +#define SCAN_CONTROL_W 23 +#define SCAN_CONTROL_Z 26 + + +typedef +EFI_STATUS +(*MENU_ITEM_FUNCTION) ( + VOID + ); + +typedef struct _EDITOR_MENU_ITEM { + EFI_STRING_ID NameToken; + CHAR16 FunctionKeyToken; + MENU_ITEM_FUNCTION Function; +} EDITOR_MENU_ITEM; + +/** + Initializa the menu bar with the specified items. + + @param[in] Items The items to display and their functions. + + @retval EFI_SUCCESS The initialization was correct. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MenuBarInit ( + IN CONST EDITOR_MENU_ITEM *Items + ); + +/** + Initialize the control hot-key with the specified items. + + @param[in] Items The hot-key functions. + + @retval EFI_SUCCESS The initialization was correct. +**/ +EFI_STATUS +ControlHotKeyInit ( + IN MENU_ITEM_FUNCTION *Items + ); + +/** + Cleanup function for a menu bar. frees all allocated memory. +**/ +VOID +MenuBarCleanup ( + VOID + ); + +/** + Refresh function for the menu bar. + + @param[in] LastRow The last printable row. + @param[in] LastCol The last printable column. + + @retval EFI_SUCCESS The refresh was successful. +**/ +EFI_STATUS +MenuBarRefresh ( + IN CONST UINTN LastRow, + IN CONST UINTN LastCol + ); + +/** + Function to dispatch the correct function based on a function key (F1...) + + @param[in] Key The pressed key. + + @retval EFI_NOT_FOUND The key was not a valid function key + (an error was sent to the status bar). + @return The return value from the called dispatch function. +**/ +EFI_STATUS +MenuBarDispatchFunctionKey ( + IN CONST EFI_INPUT_KEY *Key + ); + +/** + Function to dispatch the correct function based on a control-based key (ctrl+o...) + + @param[in] KeyData The pressed key. + + @retval EFI_NOT_FOUND The key was not a valid control-based key + (an error was sent to the status bar). + @return EFI_SUCCESS. +**/ +EFI_STATUS +MenuBarDispatchControlHotKey ( + IN CONST EFI_KEY_DATA *KeyData + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.c new file mode 100644 index 00000000..dfa1b2c3 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.c @@ -0,0 +1,224 @@ +/** @file + Implements statusbar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "EditStatusBar.h" +#include "UefiShellDebug1CommandsLib.h" + +CHAR16 *StatusString; +BOOLEAN StatusBarNeedRefresh; +BOOLEAN StatusStringChanged; + +/** + Initialization function for Status Bar. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @sa StatusBarSetStatusString +**/ +EFI_STATUS +StatusBarInit ( + VOID + ) +{ + // + // initialize the statusbar + // + StatusString = NULL; + StatusBarNeedRefresh = TRUE; + StatusStringChanged = FALSE; + + // + // status string set to "" + // + return (StatusBarSetStatusString (L"")); +} + +/** + Cleanup function for the status bar. +**/ +VOID +StatusBarCleanup ( + VOID + ) +{ + // + // free the status string and backvar's status string + // + SHELL_FREE_NON_NULL (StatusString); +} + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 3; +} STATUS_BAR_COLOR_ATTRIBUTES; + +typedef union { + STATUS_BAR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} STATUS_BAR_COLOR_UNION; + +/** + Cause the status bar to refresh it's printing on the screen. + + @param[in] EditorFirst TRUE to indicate the first launch of the editor. + FALSE otherwise. + @param[in] LastRow LastPrintable row. + @param[in] LastCol Last printable column. + @param[in] FileRow Row in the file. + @param[in] FileCol Column in the file. + @param[in] InsertMode TRUE to indicate InsertMode. FALSE otherwise. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +StatusBarRefresh ( + IN BOOLEAN EditorFirst, + IN UINTN LastRow, + IN UINTN LastCol, + IN UINTN FileRow, + IN UINTN FileCol, + IN BOOLEAN InsertMode + ) +{ + STATUS_BAR_COLOR_UNION Orig; + STATUS_BAR_COLOR_UNION New; + + if (!StatusStringChanged && StatusBarNeedRefresh) { + StatusBarSetStatusString (L"\0"); + } + // + // when it's called first time after editor launch, so refresh is mandatory + // + if (!StatusBarNeedRefresh && !StatusStringChanged) { + return EFI_SUCCESS; + } + + // + // back up the screen attributes + // + Orig.Data = gST->ConOut->Mode->Attribute; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + + // + // clear status bar + // + EditorClearLine (LastRow, LastCol, LastRow); + + // + // print row, column fields + // + if (FileRow != (UINTN)(-1) && FileCol != (UINTN)(-1)) { + ShellPrintEx ( + 0, + (INT32)(LastRow) - 1, + L" %d,%d %s", + FileRow, + FileCol, + StatusString + ); + } else { + ShellPrintEx ( + 0, + (INT32)(LastRow) - 1, + L" %s", + StatusString + ); + } + + // + // print insert mode field + // + if (InsertMode) { + ShellPrintEx ((INT32)(LastCol) - 21, (INT32)(LastRow) - 1, L"|%s| Help: Ctrl-E", L"INS"); + } else { + ShellPrintEx ((INT32)(LastCol) - 21, (INT32)(LastRow) - 1, L"|%s| Help: Ctrl-E", L"OVR"); + } + // + // restore the old screen attributes + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + + // + // restore position in edit area + // + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + StatusBarNeedRefresh = FALSE; + StatusStringChanged = FALSE; + + return EFI_SUCCESS; +} + +/** + Set the status string text part. + + @param[in] Str The string to use. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +StatusBarSetStatusString ( + IN CHAR16 *Str + ) +{ + StatusStringChanged = TRUE; + + // + // free the old status string + // + SHELL_FREE_NON_NULL (StatusString); + StatusString = CatSPrint (NULL, L"%s", Str); + if (StatusString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Function to retrieve the current status string. + + @return The string that is used. +**/ +CONST CHAR16* +StatusBarGetString ( + VOID + ) +{ + return (StatusString); +} + +/** + Function to set the need refresh boolean to TRUE. +**/ +VOID +StatusBarSetRefresh( + VOID + ) +{ + StatusBarNeedRefresh = TRUE; +} + +/** + Function to get the need refresh boolean to TRUE. + + @retval TRUE The status bar needs to be refreshed. +**/ +BOOLEAN +StatusBarGetRefresh( + VOID + ) +{ + return (StatusBarNeedRefresh); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.h new file mode 100644 index 00000000..cd77fa7c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditStatusBar.h @@ -0,0 +1,96 @@ +/** @file + Declares statusbar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_STATUS_BAR_H_ +#define _LIB_STATUS_BAR_H_ + +/** + Initialization function for Status Bar. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @sa StatusBarSetStatusString +**/ +EFI_STATUS +StatusBarInit ( + VOID + ); + +/** + Cleanup function for the status bar. +**/ +VOID +StatusBarCleanup ( + VOID + ); + +/** + Cause the status bar to refresh it's printing on the screen. + + @param[in] EditorFirst TRUE to indicate the first launch of the editor. + FALSE otherwise. + @param[in] LastRow LastPrintable row. + @param[in] LastCol Last printable column. + @param[in] FileRow Row in the file. + @param[in] FileCol Column in the file. + @param[in] InsertMode TRUE to indicate InsertMode. FALSE otherwise. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +StatusBarRefresh ( + IN BOOLEAN EditorFirst, + IN UINTN LastRow, + IN UINTN LastCol, + IN UINTN FileRow, + IN UINTN FileCol, + IN BOOLEAN InsertMode + ); + +/** + Set the status string text part. + + @param[in] Str The string to use. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +StatusBarSetStatusString ( + IN CHAR16 *Str + ); + +/** + Function to retrieve the current status string. + + @return The string that is used. +**/ +CONST CHAR16* +StatusBarGetString ( + VOID + ); + +/** + Function to set the need refresh boolean to TRUE. +**/ +VOID +StatusBarSetRefresh( + VOID + ); + +/** + Function to get the need refresh boolean to TRUE. + + @retval TRUE The status bar needs to be refreshed. +**/ +BOOLEAN +StatusBarGetRefresh( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.c new file mode 100644 index 00000000..97ef2e88 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.c @@ -0,0 +1,201 @@ +/** @file + Implements titlebar interface functions. + + (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "EditTitleBar.h" +#include "UefiShellDebug1CommandsLib.h" + +CHAR16 *Title = NULL; + +/** + Initialize a title bar. + + @param[in] Prompt The prompt to print in the title bar. + + @retval EFI_SUCCESS The initialization was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainTitleBarInit ( + CONST CHAR16 *Prompt + ) +{ + SHELL_FREE_NON_NULL (Title); + if (Prompt == NULL) { + Title = CatSPrint (NULL, L""); + } else { + // + // set Title + // + Title = CatSPrint (NULL, L"%s", Prompt); + } + if (Title == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Clean up the memory used. +**/ +VOID +MainTitleBarCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (Title); + Title = NULL; +} + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 4; +} TITLE_BAR_COLOR_ATTRIBUTES; + +typedef union { + TITLE_BAR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} TITLE_BAR_COLOR_UNION; + +/** + Refresh function for MainTitleBar + + @param[in] FileName The open file's name (or NULL). + @param[in] FileType The type fo the file. + @param[in] ReadOnly TRUE if the file is read only. FALSE otherwise. + @param[in] Modified TRUE if the file was modified. FALSE otherwise. + @param[in] LastCol The last printable column. + @param[in] LastRow The last printable row. + @param[in] Offset The offset into the file. (only for mem/disk) + @param[in] Size The file's size. (only for mem/disk) + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainTitleBarRefresh ( + IN CONST CHAR16 *FileName OPTIONAL, + IN CONST EDIT_FILE_TYPE FileType, + IN CONST BOOLEAN ReadOnly, + IN CONST BOOLEAN Modified, + IN CONST UINTN LastCol, + IN CONST UINTN LastRow, + IN CONST UINTN Offset, + IN CONST UINTN Size + ) +{ + TITLE_BAR_COLOR_UNION Orig; + TITLE_BAR_COLOR_UNION New; + CONST CHAR16 *FileNameTmp; + INTN TempInteger; + + + // + // backup the old screen attributes + // + Orig.Data = gST->ConOut->Mode->Attribute; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + + // + // clear the title line + // + EditorClearLine (1, LastCol, LastRow); + + if (Title != NULL) { + // + // print the new title bar prefix + // + ShellPrintEx ( + 0, + 0, + L"%s ", + Title + ); + } + if (FileName == NULL) { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + return EFI_SUCCESS; + } + // + // First Extract the FileName from fullpath + // + FileNameTmp = FileName; + for (TempInteger = StrLen (FileNameTmp) - 1; TempInteger >= 0; TempInteger--) { + if (FileNameTmp[TempInteger] == L'\\') { + break; + } + } + + FileNameTmp = FileNameTmp + TempInteger + 1; + + // + // the space for file name is 20 characters + // + if (StrLen (FileNameTmp) <= 20) { + ShellPrintEx (-1,-1, L"%s ", FileNameTmp); + for (TempInteger = StrLen (FileNameTmp); TempInteger < 20; TempInteger++) { + ShellPrintEx (-1,-1, L" "); + } + + } else { + for (TempInteger = 0; TempInteger < 17; TempInteger++) { + ShellPrintEx (-1,-1, L"%c", FileNameTmp[TempInteger]); + } + // + // print "..." + // + ShellPrintEx (-1,-1, L"... "); + } + // + // print file type field + // + switch (FileType){ + case FileTypeAscii: + case FileTypeUnicode: + if (FileType == FileTypeAscii){ + ShellPrintEx (-1,-1, L" ASCII "); + } else { + ShellPrintEx (-1,-1, L" UNICODE "); + } + // + // print read-only field for text files + // + if (ReadOnly) { + ShellPrintEx (-1,-1, L"ReadOnly "); + } else { + ShellPrintEx (-1,-1, L" "); + } + break; + case FileTypeDiskBuffer: + case FileTypeMemBuffer: + // + // Print the offset. + // + ShellPrintEx (-1,-1, L"Offset %X | Size %X", Offset, Size); + case FileTypeFileBuffer: + break; + default: + break; + } + // + // print modified field + // + if (Modified) { + ShellPrintEx (-1,-1, L"Modified"); + } + // + // restore the old attribute + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.h new file mode 100644 index 00000000..406d0286 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditTitleBar.h @@ -0,0 +1,68 @@ +/** @file + Declares titlebar interface functions. + + Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_TITLE_BAR_H_ +#define _LIB_TITLE_BAR_H_ + +/** + Initialize a title bar. + + @param[in] Prompt The prompt to print in the title bar. + + @retval EFI_SUCCESS The initialization was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +MainTitleBarInit ( + CONST CHAR16 *Prompt + ); + +/** + Clean up the memory used. +**/ +VOID +MainTitleBarCleanup ( + VOID + ); + +typedef enum { + FileTypeNone, + FileTypeAscii, + FileTypeUnicode, + FileTypeDiskBuffer, + FileTypeMemBuffer, + FileTypeFileBuffer +} EDIT_FILE_TYPE; + +/** + Refresh function for MainTitleBar + + @param[in] FileName The open file's name (or NULL). + @param[in] FileType The type fo the file. + @param[in] ReadOnly TRUE if the file is read only. FALSE otherwise. + @param[in] Modified TRUE if the file was modified. FALSE otherwise. + @param[in] LastCol The last printable column. + @param[in] LastRow The last printable row. + @param[in] Offset The offset into the file. (only for mem/disk) + @param[in] Size The file's size. (only for mem/disk) + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +MainTitleBarRefresh ( + IN CONST CHAR16 *FileName OPTIONAL, + IN CONST EDIT_FILE_TYPE FileType, + IN CONST BOOLEAN ReadOnly, + IN CONST BOOLEAN Modified, + IN CONST UINTN LastCol, + IN CONST UINTN LastRow, + IN CONST UINTN Offset, + IN CONST UINTN Size + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c new file mode 100644 index 00000000..ceb30c91 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c @@ -0,0 +1,158 @@ +/** @file + Main file for EfiCompress shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "Compress.h" + +/** + Function for 'compress' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEfiCompress ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + SHELL_FILE_HANDLE InShellFileHandle; + SHELL_FILE_HANDLE OutShellFileHandle; + UINT64 OutSize; + UINTN OutSize2; + VOID *OutBuffer; + UINT64 InSize; + UINTN InSize2; + VOID *InBuffer; + CHAR16 *InFileName; + CONST CHAR16 *OutFileName; + CONST CHAR16 *TempParam; + + InFileName = NULL; + OutFileName = NULL; + OutSize = 0; + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + OutBuffer = NULL; + InShellFileHandle = NULL; + OutShellFileHandle = NULL; + InBuffer = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"eficompress", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"eficompress"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) < 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"eficompress"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + TempParam = ShellCommandLineGetRawValue(Package, 1); + ASSERT(TempParam != NULL); + InFileName = ShellFindFilePath(TempParam); + OutFileName = ShellCommandLineGetRawValue(Package, 2); + if (InFileName == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"eficompress", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } else { + if (ShellIsDirectory(InFileName) == EFI_SUCCESS){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", InFileName); + ShellStatus = SHELL_INVALID_PARAMETER; + } + if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", OutFileName); + ShellStatus = SHELL_INVALID_PARAMETER; + } + if (ShellStatus == SHELL_SUCCESS) { + Status = ShellOpenFileByName(InFileName, &InShellFileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 1)); + ShellStatus = SHELL_NOT_FOUND; + } + Status = ShellOpenFileByName(OutFileName, &OutShellFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 2)); + ShellStatus = SHELL_NOT_FOUND; + } + } + if (ShellStatus == SHELL_SUCCESS) { + Status = gEfiShellProtocol->GetFileSize(InShellFileHandle, &InSize); + ASSERT_EFI_ERROR(Status); + InBuffer = AllocateZeroPool((UINTN)InSize); + if (InBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + InSize2 = (UINTN) InSize; + Status = gEfiShellProtocol->ReadFile (InShellFileHandle, &InSize2, InBuffer); + InSize = InSize2; + ASSERT_EFI_ERROR (Status); + Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + OutBuffer = AllocateZeroPool ((UINTN) OutSize); + if (OutBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); + } + } + } + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); + ShellStatus = ((Status == EFI_OUT_OF_RESOURCES) ? SHELL_OUT_OF_RESOURCES : SHELL_DEVICE_ERROR); + } else { + OutSize2 = (UINTN)OutSize; + Status = gEfiShellProtocol->WriteFile(OutShellFileHandle, &OutSize2, OutBuffer); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"eficompress", OutFileName); + ShellStatus = SHELL_DEVICE_ERROR; + } + } + } + } + } + + ShellCommandLineFreeVarList (Package); + } + if (InShellFileHandle != NULL) { + gEfiShellProtocol->CloseFile(InShellFileHandle); + } + if (OutShellFileHandle != NULL) { + gEfiShellProtocol->CloseFile(OutShellFileHandle); + } + SHELL_FREE_NON_NULL(InFileName); + SHELL_FREE_NON_NULL(InBuffer); + SHELL_FREE_NON_NULL(OutBuffer); + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiDecompress.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiDecompress.c new file mode 100644 index 00000000..307cdd4c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiDecompress.c @@ -0,0 +1,180 @@ +/** @file + Main file for EfiDecompress shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Protocol/Decompress.h> + + +/** + Function for 'decompress' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEfiDecompress ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + SHELL_FILE_HANDLE InFileHandle; + SHELL_FILE_HANDLE OutFileHandle; + UINT32 OutSize; + UINTN OutSizeTemp; + VOID *OutBuffer; + UINTN InSize; + VOID *InBuffer; + CHAR16 *InFileName; + CONST CHAR16 *OutFileName; + UINT64 Temp64Bit; + UINT32 ScratchSize; + VOID *ScratchBuffer; + EFI_DECOMPRESS_PROTOCOL *Decompress; + CONST CHAR16 *TempParam; + + InFileName = NULL; + OutFileName = NULL; + OutSize = 0; + ScratchSize = 0; + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + OutBuffer = NULL; + InBuffer = NULL; + ScratchBuffer = NULL; + InFileHandle = NULL; + OutFileHandle = NULL; + Decompress = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"efidecompress", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"efidecompress"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) < 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"efidecompress"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + TempParam = ShellCommandLineGetRawValue(Package, 1); + ASSERT(TempParam != NULL); + InFileName = ShellFindFilePath(TempParam); + OutFileName = ShellCommandLineGetRawValue(Package, 2); + if (InFileName == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"efidecompress", TempParam); + ShellStatus = SHELL_NOT_FOUND; + } else { + if (ShellIsDirectory(InFileName) == EFI_SUCCESS){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", InFileName); + ShellStatus = SHELL_INVALID_PARAMETER; + } + if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", OutFileName); + ShellStatus = SHELL_INVALID_PARAMETER; + } + if (ShellStatus == SHELL_SUCCESS) { + Status = ShellOpenFileByName(InFileName, &InFileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"efidecompress", ShellCommandLineGetRawValue(Package, 1)); + ShellStatus = SHELL_NOT_FOUND; + } + } + + if (ShellStatus == SHELL_SUCCESS) { + Status = FileHandleGetSize(InFileHandle, &Temp64Bit); + ASSERT(Temp64Bit <= (UINT32)(-1)); + InSize = (UINTN)Temp64Bit; + ASSERT_EFI_ERROR(Status); + InBuffer = AllocateZeroPool(InSize); + if (InBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = gEfiShellProtocol->ReadFile (InFileHandle, &InSize, InBuffer); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID**) &Decompress); + ASSERT_EFI_ERROR (Status); + + Status = Decompress->GetInfo (Decompress, InBuffer, (UINT32) InSize, &OutSize, &ScratchSize); + } + + if (EFI_ERROR(Status) || OutSize == 0) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_NOPE), gShellDebug1HiiHandle, InFileName); + ShellStatus = SHELL_NOT_FOUND; + } else { + Status = ShellOpenFileByName(OutFileName, &OutFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, 2), Status); + ShellStatus = SHELL_NOT_FOUND; + } else { + OutBuffer = AllocateZeroPool(OutSize); + ScratchBuffer = AllocateZeroPool(ScratchSize); + if (OutBuffer == NULL || ScratchBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + Status = Decompress->Decompress (Decompress, InBuffer, (UINT32) InSize, OutBuffer, OutSize, ScratchBuffer, ScratchSize); + } + } + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_FAIL), gShellDebug1HiiHandle, Status); + ShellStatus = ((Status == EFI_OUT_OF_RESOURCES) ? SHELL_OUT_OF_RESOURCES : SHELL_DEVICE_ERROR); + } else { + OutSizeTemp = OutSize; + Status = gEfiShellProtocol->WriteFile (OutFileHandle, &OutSizeTemp, OutBuffer); + OutSize = (UINT32) OutSizeTemp; + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"efidecompress", OutFileName, Status); + ShellStatus = SHELL_DEVICE_ERROR; + } + } + } + } + } + + ShellCommandLineFreeVarList (Package); + } + if (InFileHandle != NULL) { + gEfiShellProtocol->CloseFile(InFileHandle); + } + if (OutFileHandle != NULL) { + gEfiShellProtocol->CloseFile(OutFileHandle); + } + + SHELL_FREE_NON_NULL(InFileName); + SHELL_FREE_NON_NULL(InBuffer); + SHELL_FREE_NON_NULL(OutBuffer); + SHELL_FREE_NON_NULL(ScratchBuffer); + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c new file mode 100644 index 00000000..70103cc6 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c @@ -0,0 +1,2469 @@ +/** @file + Defines HBufferImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; + +extern HEFI_EDITOR_FILE_IMAGE HFileImage; +extern HEFI_EDITOR_DISK_IMAGE HDiskImage; +extern HEFI_EDITOR_MEM_IMAGE HMemImage; + +extern HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar; +extern HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar; +extern HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar; + +extern BOOLEAN HEditorMouseAction; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar; + +HEFI_EDITOR_BUFFER_IMAGE HBufferImage; +HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar; + +// +// for basic initialization of HBufferImage +// +HEFI_EDITOR_BUFFER_IMAGE HBufferImageConst = { + NULL, + NULL, + 0, + NULL, + { + 0, + 0 + }, + { + 0, + 0 + }, + { + 0, + 0 + }, + 0, + TRUE, + FALSE, + FileTypeNone, + NULL, + NULL, + NULL +}; + +// +// the whole edit area needs to be refreshed +// +BOOLEAN HBufferImageNeedRefresh; + +// +// only the current line in edit area needs to be refresh +// +BOOLEAN HBufferImageOnlyLineNeedRefresh; + +BOOLEAN HBufferImageMouseNeedRefresh; + +/** + Initialization function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HBufferImageInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // basically initialize the HBufferImage + // + CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage)); + + // + // INIT listhead + // + HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY)); + if (HBufferImage.ListHead == NULL) { + return EFI_LOAD_ERROR; + } + + InitializeListHead (HBufferImage.ListHead); + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.FileImage = &HFileImage; + HBufferImage.DiskImage = &HDiskImage; + HBufferImage.MemImage = &HMemImage; + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = FALSE; + + HBufferImageBackupVar.FileImage = &HFileImageBackupVar; + HBufferImageBackupVar.DiskImage = &HDiskImageBackupVar; + HBufferImageBackupVar.MemImage = &HMemImageBackupVar; + + Status = HFileImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + Status = HDiskImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + Status = HMemImageInit (); + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Backup function for HBufferImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageBackup ( + VOID + ) +{ + HBufferImageBackupVar.MousePosition = HBufferImage.MousePosition; + + HBufferImageBackupVar.BufferPosition = HBufferImage.BufferPosition; + + HBufferImageBackupVar.Modified = HBufferImage.Modified; + + HBufferImageBackupVar.BufferType = HBufferImage.BufferType; + HBufferImageBackupVar.LowVisibleRow = HBufferImage.LowVisibleRow; + HBufferImageBackupVar.HighBits = HBufferImage.HighBits; + + // + // three kinds of buffer supported + // file buffer + // disk buffer + // memory buffer + // + switch (HBufferImage.BufferType) { + case FileTypeFileBuffer: + HFileImageBackup (); + break; + + case FileTypeDiskBuffer: + HDiskImageBackup (); + break; + + case FileTypeMemBuffer: + HMemImageBackup (); + break; + + default: + break; + } + + return EFI_SUCCESS; +} + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFreeLines ( + VOID + ) +{ + HFreeLines (HBufferImage.ListHead, HBufferImage.Lines); + + HBufferImage.Lines = NULL; + HBufferImage.CurrentLine = NULL; + HBufferImage.NumLines = 0; + + return EFI_SUCCESS; +} + +/** + Cleanup function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageCleanup ( + VOID + ) +{ + EFI_STATUS Status; + + // + // free all the lines + // + Status = HBufferImageFreeLines (); + + SHELL_FREE_NON_NULL (HBufferImage.ListHead); + HBufferImage.ListHead = NULL; + + HFileImageCleanup (); + HDiskImageCleanup (); + + return Status; + +} + +/** + Print Line on Row + + @param[in] Line The lline to print. + @param[in] Row The row on screen ( begin from 1 ). + @param[in] FRow The FRow. + @param[in] Orig The original color. + @param[in] New The color to print with. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePrintLine ( + IN HEFI_EDITOR_LINE *Line, + IN UINTN Row, + IN UINTN FRow, + IN HEFI_EDITOR_COLOR_UNION Orig, + IN HEFI_EDITOR_COLOR_UNION New + + ) +{ + + UINTN Index; + UINTN Pos; + BOOLEAN Selected; + BOOLEAN BeNewColor; + UINTN RowStart; + UINTN RowEnd; + UINTN ColStart; + UINTN ColEnd; + + // + // variable initialization + // + ColStart = 0; + ColEnd = 0; + Selected = FALSE; + + // + // print the selected area in opposite color + // + if (HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) { + RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1; + RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + + ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1; + ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1; + + if (FRow >= RowStart && FRow <= RowEnd) { + Selected = TRUE; + } + + if (FRow > RowStart) { + ColStart = 1; + } + + if (FRow < RowEnd) { + ColEnd = 0x10; + } + + } + + if (!HEditorMouseAction) { + ShellPrintEx ( + 0, + (INT32)Row - 1, + L"%8X ", + ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10 + ); + + } + + for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) { + + BeNewColor = FALSE; + + if (Selected) { + if (Index + 1 >= ColStart && Index + 1 <= ColEnd) { + BeNewColor = TRUE; + } + } + + if (BeNewColor) { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + } + + Pos = 10 + (Index * 3); + if (Line->Buffer[Index] < 0x10) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0"); + Pos++; + } + + if (Index < 0x07) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + } else { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + } + + } + + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + while (Index < 0x08) { + Pos = 10 + (Index * 3); + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + + while (Index < 0x10 && Index < Line->Size) { + + BeNewColor = FALSE; + + if (Selected) { + if (Index + 1 >= ColStart && Index + 1 <= ColEnd) { + BeNewColor = TRUE; + } + } + + if (BeNewColor) { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + } + + Pos = 10 + (Index * 3) + 1; + if (Line->Buffer[Index] < 0x10) { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0"); + Pos++; + } + + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]); + Index++; + } + + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + while (Index < 0x10) { + Pos = 10 + (Index * 3) + 1; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + // + // restore the original color + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F); + + // + // PRINT the buffer content + // + if (!HEditorMouseAction) { + for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) { + Pos = ASCII_POSITION + Index; + + // + // learned from shelle.h -- IsValidChar + // + if (Line->Buffer[Index] >= L' ') { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16) Line->Buffer[Index]); + } else { + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.'); + } + } + + while (Index < 0x10) { + Pos = ASCII_POSITION + Index; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + Index++; + } + } + // + // restore the abundant blank in hex edit area to original color + // + if (Selected) { + if (ColEnd <= 7) { + Pos = 10 + (ColEnd - 1) * 3 + 2; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } else if (ColEnd == 8) { + Pos = 10 + (ColEnd - 1) * 3 + 2; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } else { + Pos = 10 + (ColEnd - 1) * 3 + 3; + ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" "); + } + } + + return EFI_SUCCESS; +} + +/** + Function to decide if a column number is stored in the high bits. + + @param[in] Column The column to examine. + @param[out] FCol The actual column number. + + @retval TRUE The actual column was in high bits and is now in FCol. + @retval FALSE There was not a column number in the high bits. +**/ +BOOLEAN +HBufferImageIsAtHighBits ( + IN UINTN Column, + OUT UINTN *FCol + ) +{ + Column -= 10; + + // + // NOW AFTER THE SUB, Column start from 0 + // 23 AND 24 ARE BOTH BLANK + // + if (Column == 24) { + *FCol = 0; + return FALSE; + } + + if (Column > 24) { + Column--; + } + + *FCol = (Column / 3) + 1; + + if (Column % 3 == 0) { + return TRUE; + } + + if ((Column % 3 == 2)) { + *FCol = 0; + } + + return FALSE; +} + +/** + Decide if a point is in the already selected area. + + @param[in] MouseRow The row of the point to test. + @param[in] MouseCol The col of the point to test. + + @retval TRUE The point is in the selected area. + @retval FALSE The point is not in the selected area. +**/ +BOOLEAN +HBufferImageIsInSelectedArea ( + IN UINTN MouseRow, + IN UINTN MouseCol + ) +{ + UINTN FRow; + UINTN RowStart; + UINTN RowEnd; + UINTN ColStart; + UINTN ColEnd; + UINTN MouseColStart; + UINTN MouseColEnd; + + // + // judge mouse position whether is in selected area + // + // + // not select + // + if (HMainEditor.SelectStart == 0 || HMainEditor.SelectEnd == 0) { + return FALSE; + } + // + // calculate the select area + // + RowStart = (HMainEditor.SelectStart - 1) / 0x10 + 1; + RowEnd = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + + ColStart = (HMainEditor.SelectStart - 1) % 0x10 + 1; + ColEnd = (HMainEditor.SelectEnd - 1) % 0x10 + 1; + + FRow = HBufferImage.LowVisibleRow + MouseRow - 2; + if (FRow < RowStart || FRow > RowEnd) { + return FALSE; + } + + if (FRow > RowStart) { + ColStart = 1; + } + + if (FRow < RowEnd) { + ColEnd = 0x10; + } + + MouseColStart = 10 + (ColStart - 1) * 3; + if (ColStart > 8) { + MouseColStart++; + } + + MouseColEnd = 10 + (ColEnd - 1) * 3 + 1; + if (ColEnd > 8) { + MouseColEnd++; + } + + if (MouseCol < MouseColStart || MouseCol > MouseColEnd) { + return FALSE; + } + + return TRUE; +} + +/** + Set mouse position according to HBufferImage.MousePosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRestoreMousePosition ( + VOID + ) +{ + HEFI_EDITOR_COLOR_UNION Orig; + HEFI_EDITOR_COLOR_UNION New; + UINTN FRow; + UINTN FColumn; + BOOLEAN HasCharacter; + HEFI_EDITOR_LINE *CurrentLine; + HEFI_EDITOR_LINE *Line; + UINT8 Value; + BOOLEAN HighBits; + + Line = NULL; + if (HMainEditor.MouseSupported) { + + if (HBufferImageMouseNeedRefresh) { + + HBufferImageMouseNeedRefresh = FALSE; + + // + // if mouse position not moved and only mouse action + // so do not need to refresh mouse position + // + if (( + HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row && + HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column + ) && + HEditorMouseAction + ) { + return EFI_SUCCESS; + } + // + // backup the old screen attributes + // + Orig = HMainEditor.ColorAttributes; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + // + // if in selected area, + // so do not need to refresh mouse + // + if (!HBufferImageIsInSelectedArea ( + HBufferImageBackupVar.MousePosition.Row, + HBufferImageBackupVar.MousePosition.Column + )) { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } else { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } + // + // clear the old mouse position + // + FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2; + + HighBits = HBufferImageIsAtHighBits ( + HBufferImageBackupVar.MousePosition.Column, + &FColumn + ); + + HasCharacter = TRUE; + if (FRow > HBufferImage.NumLines || FColumn == 0) { + HasCharacter = FALSE; + } else { + CurrentLine = HBufferImage.CurrentLine; + Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row); + + if (Line == NULL || FColumn > Line->Size) { + HasCharacter = FALSE; + } + + HBufferImage.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)HBufferImageBackupVar.MousePosition.Column - 1, + (INT32)HBufferImageBackupVar.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + if (HighBits) { + Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0); + Value = (UINT8) (Value >> 4); + } else { + Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf); + } + + ShellPrintEx ( + (INT32)HBufferImageBackupVar.MousePosition.Column - 1, + (INT32)HBufferImageBackupVar.MousePosition.Row - 1, + L"%x", + Value + ); + } + + if (!HBufferImageIsInSelectedArea ( + HBufferImage.MousePosition.Row, + HBufferImage.MousePosition.Column + )) { + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + } else { + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } + // + // clear the old mouse position + // + FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2; + + HighBits = HBufferImageIsAtHighBits ( + HBufferImage.MousePosition.Column, + &FColumn + ); + + HasCharacter = TRUE; + if (FRow > HBufferImage.NumLines || FColumn == 0) { + HasCharacter = FALSE; + } else { + CurrentLine = HBufferImage.CurrentLine; + Line = HMoveLine (FRow - HBufferImage.BufferPosition.Row); + + if (Line == NULL || FColumn > Line->Size) { + HasCharacter = FALSE; + } + + HBufferImage.CurrentLine = CurrentLine; + } + + ShellPrintEx ( + (INT32)HBufferImage.MousePosition.Column - 1, + (INT32)HBufferImage.MousePosition.Row - 1, + L" " + ); + + if (HasCharacter) { + if (HighBits) { + Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0); + Value = (UINT8) (Value >> 4); + } else { + Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf); + } + + ShellPrintEx ( + (INT32)HBufferImage.MousePosition.Column - 1, + (INT32)HBufferImage.MousePosition.Row - 1, + L"%x", + Value + ); + } + // + // end of HasCharacter + // + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } + // + // end of MouseNeedRefresh + // + } + // + // end of MouseSupported + // + return EFI_SUCCESS; +} + +/** + Set cursor position according to HBufferImage.DisplayPosition. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRestorePosition ( + VOID + ) +{ + // + // set cursor position + // + gST->ConOut->SetCursorPosition ( + gST->ConOut, + HBufferImage.DisplayPosition.Column - 1, + HBufferImage.DisplayPosition.Row - 1 + ); + + return EFI_SUCCESS; +} + +/** + Refresh function for HBufferImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A Load error occurred. + +**/ +EFI_STATUS +HBufferImageRefresh ( + VOID + ) +{ + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + UINTN Row; + HEFI_EDITOR_COLOR_UNION Orig; + HEFI_EDITOR_COLOR_UNION New; + + UINTN StartRow; + UINTN EndRow; + UINTN FStartRow; + UINTN Tmp; + + Orig = HMainEditor.ColorAttributes; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background; + New.Colors.Background = Orig.Colors.Foreground; + + // + // if it's the first time after editor launch, so should refresh + // + if (HEditorFirst == FALSE) { + // + // no definite required refresh + // and file position displayed on screen has not been changed + // + if (!HBufferImageNeedRefresh && + !HBufferImageOnlyLineNeedRefresh && + HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow + ) { + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + return EFI_SUCCESS; + } + } + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + // + // only need to refresh current line + // + if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) { + + HBufferImagePrintLine ( + HBufferImage.CurrentLine, + HBufferImage.DisplayPosition.Row, + HBufferImage.BufferPosition.Row, + Orig, + New + ); + } else { + // + // the whole edit area need refresh + // + if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) { + if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) { + if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) { + StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1; + } else { + StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1; + } + } else { + StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1; + } + + if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) { + EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1; + } else { + EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1; + } + // + // swap + // + if (StartRow > EndRow) { + Tmp = StartRow; + StartRow = EndRow; + EndRow = Tmp; + } + + FStartRow = StartRow; + + StartRow = 2 + StartRow - HBufferImage.LowVisibleRow; + EndRow = 2 + EndRow - HBufferImage.LowVisibleRow; + + } else { + // + // not mouse selection actions + // + FStartRow = HBufferImage.LowVisibleRow; + StartRow = 2; + EndRow = (HMainEditor.ScreenSize.Row - 1); + } + // + // no line + // + if (HBufferImage.Lines == NULL) { + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_SUCCESS; + } + // + // get the first line that will be displayed + // + Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row); + if (Line == NULL) { + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_LOAD_ERROR; + } + + Link = &(Line->Link); + Row = StartRow; + do { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // + // print line at row + // + HBufferImagePrintLine ( + Line, + Row, + HBufferImage.LowVisibleRow + Row - 2, + Orig, + New + ); + + Link = Link->ForwardLink; + Row++; + } while (Link != HBufferImage.ListHead && Row <= EndRow); + + while (Row <= EndRow) { + EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row); + Row++; + } + // + // while not file end and not screen full + // + } + + HBufferImageRestoreMousePosition (); + HBufferImageRestorePosition (); + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + return EFI_SUCCESS; +} + +/** + Read an image into a buffer friom a source. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + @param[in] Recover TRUE for recovermode, FALSE otherwise. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRead ( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType, + IN BOOLEAN Recover + ) +{ + EFI_STATUS Status; + EDIT_FILE_TYPE BufferTypeBackup; + + // + // variable initialization + // + Status = EFI_SUCCESS; + HBufferImage.BufferType = BufferType; + + // + // three types of buffer supported + // file buffer + // disk buffer + // memory buffer + // + BufferTypeBackup = HBufferImage.BufferType; + + switch (BufferType) { + case FileTypeFileBuffer: + Status = HFileImageRead (FileName, Recover); + break; + + case FileTypeDiskBuffer: + Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover); + break; + + case FileTypeMemBuffer: + Status = HMemImageRead (MemOffset, MemSize, Recover); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + + if (EFI_ERROR (Status)) { + HBufferImage.BufferType = BufferTypeBackup; + } + + return Status; +} + +/** + Save the current image. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageSave ( + IN CHAR16 *FileName, + IN CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType + ) +{ + EFI_STATUS Status; + EDIT_FILE_TYPE BufferTypeBackup; + + // + // variable initialization + // + Status = EFI_SUCCESS; + BufferTypeBackup = HBufferImage.BufferType; + + switch (HBufferImage.BufferType) { + // + // file buffer + // + case FileTypeFileBuffer: + Status = HFileImageSave (FileName); + break; + + // + // disk buffer + // + case FileTypeDiskBuffer: + Status = HDiskImageSave (DiskName, DiskOffset, DiskSize); + break; + + // + // memory buffer + // + case FileTypeMemBuffer: + Status = HMemImageSave (MemOffset, MemSize); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + + if (EFI_ERROR (Status)) { + HBufferImage.BufferType = BufferTypeBackup; + } + + return Status; +} + +/** + Create a new line and append it to the line list. + Fields affected: + NumLines + Lines + + @retval NULL create line failed. + @return the line created. + +**/ +HEFI_EDITOR_LINE * +HBufferImageCreateLine ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + + // + // allocate for line structure + // + Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE)); + if (Line == NULL) { + return NULL; + } + + Line->Signature = EFI_EDITOR_LINE_LIST; + Line->Size = 0; + + HBufferImage.NumLines++; + + // + // insert to line list + // + InsertTailList (HBufferImage.ListHead, &Line->Link); + + if (HBufferImage.Lines == NULL) { + HBufferImage.Lines = CR ( + HBufferImage.ListHead->ForwardLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + } + + return Line; +} + +/** + Free the current image. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFree ( + VOID + ) +{ + // + // free all lines + // + HBufferImageFreeLines (); + + return EFI_SUCCESS; +} + +/** + change char to int value based on Hex. + + @param[in] Char The input char. + + @return The character's index value. + @retval -1 The operation failed. +**/ +INTN +HBufferImageCharToHex ( + IN CHAR16 Char + ) +{ + // + // change the character to hex + // + if (Char >= L'0' && Char <= L'9') { + return (Char - L'0'); + } + + if (Char >= L'a' && Char <= L'f') { + return (Char - L'a' + 10); + } + + if (Char >= L'A' && Char <= L'F') { + return (Char - L'A' + 10); + } + + return -1; +} + +/** + Add character. + + @param[in] Char -- input char. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageAddChar ( + IN CHAR16 Char + ) +{ + HEFI_EDITOR_LINE *Line; + HEFI_EDITOR_LINE *NewLine; + INTN Value; + UINT8 Old; + UINTN FRow; + UINTN FCol; + BOOLEAN High; + + Value = HBufferImageCharToHex (Char); + + // + // invalid input + // + if (Value == -1) { + return EFI_SUCCESS; + } + + Line = HBufferImage.CurrentLine; + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + High = HBufferImage.HighBits; + + // + // only needs to refresh current line + // + HBufferImageOnlyLineNeedRefresh = TRUE; + + // + // not a full line and beyond the last character + // + if (FCol > Line->Size) { + // + // cursor always at high 4 bits + // and always put input to the low 4 bits + // + Line->Buffer[Line->Size] = (UINT8) Value; + Line->Size++; + High = FALSE; + } else { + + Old = Line->Buffer[FCol - 1]; + + // + // always put the input to the low 4 bits + // + Old = (UINT8) (Old & 0x0f); + Old = (UINT8) (Old << 4); + Old = (UINT8) (Value + Old); + Line->Buffer[FCol - 1] = Old; + + // + // at the low 4 bits of the last character of a full line + // so if no next line, need to create a new line + // + if (!High && FCol == 0x10) { + + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageNeedRefresh = TRUE; + + if (Line->Link.ForwardLink == HBufferImage.ListHead) { + // + // last line + // + // create a new line + // + NewLine = HBufferImageCreateLine (); + if (NewLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // end of NULL + // + } + // + // end of == ListHead + // + } + // + // end of == 0x10 + // + // if already at end of this line, scroll it to the start of next line + // + if (FCol == 0x10 && !High) { + // + // definitely has next line + // + FRow++; + FCol = 1; + High = TRUE; + } else { + // + // if not at end of this line, just move to next column + // + if (!High) { + FCol++; + } + + if (High) { + High = FALSE; + } else { + High = TRUE; + } + + } + // + // end of ==FALSE + // + } + // + // move cursor to right + // + HBufferImageMovePosition (FRow, FCol, High); + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Delete the previous character. + + @retval EFI_SUCCESS The operationw as successful. +**/ +EFI_STATUS +HBufferImageDoBackspace ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + + UINTN FileColumn; + UINTN FPos; + BOOLEAN LastLine; + + // + // variable initialization + // + LastLine = FALSE; + + // + // already the first character + // + if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) { + return EFI_SUCCESS; + } + + FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1; + + FileColumn = HBufferImage.BufferPosition.Column; + + Line = HBufferImage.CurrentLine; + LastLine = FALSE; + if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) { + LastLine = TRUE; + } + + HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL); + + // + // if is the last line + // then only this line need to be refreshed + // + if (LastLine) { + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = TRUE; + } else { + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + } + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + ASCII key + Backspace + return. + + @param[in] Char The input char. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageDoCharInput ( + IN CHAR16 Char + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Char) { + case 0: + break; + + case 0x08: + Status = HBufferImageDoBackspace (); + break; + + case 0x09: + case 0x0a: + case 0x0d: + // + // Tabs, Returns are thought as nothing + // + break; + + default: + // + // DEAL WITH ASCII CHAR, filter out thing like ctrl+f + // + if (Char > 127 || Char < 32) { + Status = StatusBarSetStatusString (L"Unknown Command"); + } else { + Status = HBufferImageAddChar (Char); + } + + break; + } + + return Status; +} + +/** + Check user specified FileRow is above current screen. + + @param[in] FileRow Row of file position ( start from 1 ). + + @retval TRUE It is above the current screen. + @retval FALSE It is not above the current screen. + +**/ +BOOLEAN +HAboveCurrentScreen ( + IN UINTN FileRow + ) +{ + if (FileRow < HBufferImage.LowVisibleRow) { + return TRUE; + } + + return FALSE; +} + +/** + Check user specified FileRow is under current screen. + + @param[in] FileRow Row of file position ( start from 1 ). + + @retval TRUE It is under the current screen. + @retval FALSE It is not under the current screen. + +**/ +BOOLEAN +HUnderCurrentScreen ( + IN UINTN FileRow + ) +{ + if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) { + return TRUE; + } + + return FALSE; +} + +/** + According to cursor's file position, adjust screen display. + + @param[in] NewFilePosRow Row of file position ( start from 1 ). + @param[in] NewFilePosCol Column of file position ( start from 1 ). + @param[in] HighBits Cursor will on high4 bits or low4 bits. +**/ +VOID +HBufferImageMovePosition ( + IN UINTN NewFilePosRow, + IN UINTN NewFilePosCol, + IN BOOLEAN HighBits + ) +{ + INTN RowGap; + UINTN Abs; + BOOLEAN Above; + BOOLEAN Under; + UINTN NewDisplayCol; + + // + // CALCULATE gap between current file position and new file position + // + RowGap = NewFilePosRow - HBufferImage.BufferPosition.Row; + + Under = HUnderCurrentScreen (NewFilePosRow); + Above = HAboveCurrentScreen (NewFilePosRow); + + HBufferImage.HighBits = HighBits; + + // + // if is below current screen + // + if (Under) { + // + // display row will be unchanged + // + HBufferImage.BufferPosition.Row = NewFilePosRow; + } else { + if (Above) { + // + // has enough above line, so display row unchanged + // not has enough above lines, so the first line is + // at the first display line + // + if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) { + HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1; + } + + HBufferImage.BufferPosition.Row = NewFilePosRow; + } else { + // + // in current screen + // + HBufferImage.BufferPosition.Row = NewFilePosRow; + if (RowGap <= 0) { + Abs = (UINTN)ABS(RowGap); + HBufferImage.DisplayPosition.Row -= Abs; + } else { + HBufferImage.DisplayPosition.Row += RowGap; + } + + } + } + + HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2); + + // + // always in current screen + // + HBufferImage.BufferPosition.Column = NewFilePosCol; + + NewDisplayCol = 10 + (NewFilePosCol - 1) * 3; + if (NewFilePosCol > 0x8) { + NewDisplayCol++; + } + + if (!HighBits) { + NewDisplayCol++; + } + + HBufferImage.DisplayPosition.Column = NewDisplayCol; + + // + // let CurrentLine point to correct line; + // + HBufferImage.CurrentLine = HMoveCurrentLine (RowGap); + +} + +/** + Scroll cursor to right. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollRight ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + // + // scroll right will always move to the high4 bits of the next character + // + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // this line is not full and no next line + // + if (FCol > Line->Size) { + return EFI_SUCCESS; + } + // + // if already at end of this line, scroll it to the start of next line + // + if (FCol == 0x10) { + // + // has next line + // + if (Line->Link.ForwardLink != HBufferImage.ListHead) { + FRow++; + FCol = 1; + + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at end of this line, just move to next column + // + FCol++; + + } + + HBufferImageMovePosition (FRow, FCol, TRUE); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to left. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollLeft ( + VOID + ) +{ + + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = FALSE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // if already at start of this line, so move to the end of previous line + // + if (FCol <= 1) { + // + // has previous line + // + if (Line->Link.BackLink != HBufferImage.ListHead) { + FRow--; + Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + FCol = Line->Size; + } else { + return EFI_SUCCESS; + } + } else { + // + // if not at start of this line, just move to previous column + // + FCol--; + } + + HBufferImageMovePosition (FRow, FCol, TRUE); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to the next line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollDown ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + HighBits = HBufferImage.HighBits; + + // + // has next line + // + if (Line->Link.ForwardLink != HBufferImage.ListHead) { + FRow++; + Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // + // if the next line is not that long, so move to end of next line + // + if (FCol > Line->Size) { + FCol = Line->Size + 1; + HighBits = TRUE; + } + + } else { + return EFI_SUCCESS; + } + + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to previous line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageScrollUp ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // has previous line + // + if (Line->Link.BackLink != HBufferImage.ListHead) { + FRow--; + + } else { + return EFI_SUCCESS; + } + + HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to next page + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePageDown ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + UINTN Gap; + BOOLEAN HighBits; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + HighBits = HBufferImage.HighBits; + + // + // has next page + // + if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) { + Gap = (HMainEditor.ScreenSize.Row - 2); + } else { + // + // MOVE CURSOR TO LAST LINE + // + Gap = HBufferImage.NumLines - FRow; + } + // + // get correct line + // + Line = HMoveLine (Gap); + + // + // if that line, is not that long, so move to the end of that line + // + if (Line != NULL && FCol > Line->Size) { + FCol = Line->Size + 1; + HighBits = TRUE; + } + + FRow += Gap; + + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to previous page + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImagePageUp ( + VOID + ) +{ + UINTN FRow; + UINTN FCol; + UINTN Gap; + INTN Retreat; + + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + + // + // has previous page + // + if (FRow > (HMainEditor.ScreenSize.Row - 2)) { + Gap = (HMainEditor.ScreenSize.Row - 2); + } else { + // + // the first line of file will displayed on the first line of screen + // + Gap = FRow - 1; + } + + Retreat = Gap; + Retreat = -Retreat; + + FRow -= Gap; + + HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to start of line + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageHome ( + VOID + ) +{ + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + // + // curosr will at the high bit + // + FRow = HBufferImage.BufferPosition.Row; + FCol = 1; + HighBits = TRUE; + + // + // move cursor position + // + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Scroll cursor to end of line. + + @retval EFI_SUCCESS Teh operation was successful. +**/ +EFI_STATUS +HBufferImageEnd ( + VOID + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + + // + // need refresh mouse + // + HBufferImageMouseNeedRefresh = TRUE; + + Line = HBufferImage.CurrentLine; + + FRow = HBufferImage.BufferPosition.Row; + + if (Line->Size == 0x10) { + FCol = Line->Size; + HighBits = FALSE; + } else { + FCol = Line->Size + 1; + HighBits = TRUE; + } + // + // move cursor position + // + HBufferImageMovePosition (FRow, FCol, HighBits); + + return EFI_SUCCESS; +} + +/** + Get the size of the open buffer. + + @retval The size in bytes. +**/ +UINTN +HBufferImageGetTotalSize ( + VOID + ) +{ + UINTN Size; + + HEFI_EDITOR_LINE *Line; + + // + // calculate the total size of whole line list's buffer + // + if (HBufferImage.Lines == NULL) { + return 0; + } + + Line = CR ( + HBufferImage.ListHead->BackLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + // + // one line at most 0x10 + // + Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size; + + return Size; +} + +/** + Delete character from buffer. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count The Count of characters to delete. + @param[out] DeleteBuffer The DeleteBuffer. + + @retval EFI_SUCCESS Success +**/ +EFI_STATUS +HBufferImageDeleteCharacterFromBuffer ( + IN UINTN Pos, + IN UINTN Count, + OUT UINT8 *DeleteBuffer + ) +{ + UINTN Index; + + VOID *Buffer; + UINT8 *BufferPtr; + UINTN Size; + + HEFI_EDITOR_LINE *Line; + LIST_ENTRY *Link; + + UINTN OldFCol; + UINTN OldFRow; + UINTN OldPos; + + UINTN NewPos; + + EFI_STATUS Status; + + Size = HBufferImageGetTotalSize (); + + if (Size < Count) { + return EFI_LOAD_ERROR; + } + + if (Size == 0) { + return EFI_SUCCESS; + } + + // + // relocate all the HBufferImage fields + // + OldFRow = HBufferImage.BufferPosition.Row; + OldFCol = HBufferImage.BufferPosition.Column; + OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1; + + if (Pos > 0) { + // + // has character before it, + // so locate according to block's previous character + // + NewPos = Pos - 1; + + } else { + // + // has no character before it, + // so locate according to block's next character + // + NewPos = 0; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + Buffer = AllocateZeroPool (Size); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HBufferImageListToBuffer (Buffer, Size); + + BufferPtr = (UINT8 *) Buffer; + + // + // pass deleted buffer out + // + if (DeleteBuffer != NULL) { + for (Index = 0; Index < Count; Index++) { + DeleteBuffer[Index] = BufferPtr[Pos + Index]; + } + } + // + // delete the part from Pos + // + for (Index = Pos; Index < Size - Count; Index++) { + BufferPtr[Index] = BufferPtr[Index + Count]; + } + + Size -= Count; + + HBufferImageFreeLines (); + + Status = HBufferImageBufferToList (Buffer, Size); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return Status; + } + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < NewPos / 0x10; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + HBufferImage.CurrentLine = Line; + + // + // if current cursor position if inside select area + // then move it to the block's NEXT character + // + if (OldPos >= Pos && OldPos < (Pos + Count)) { + NewPos = Pos; + } else { + if (OldPos < Pos) { + NewPos = OldPos; + } else { + NewPos = OldPos - Count; + } + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + return EFI_SUCCESS; +} + +/** + Add character to buffer, add before pos. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count Count of characters to add. + @param[in] AddBuffer Add buffer. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +HBufferImageAddCharacterToBuffer ( + IN UINTN Pos, + IN UINTN Count, + IN UINT8 *AddBuffer + ) +{ + INTN Index; + + VOID *Buffer; + UINT8 *BufferPtr; + UINTN Size; + + HEFI_EDITOR_LINE *Line; + + LIST_ENTRY *Link; + + UINTN OldFCol; + UINTN OldFRow; + UINTN OldPos; + + UINTN NewPos; + + Size = HBufferImageGetTotalSize (); + + // + // relocate all the HBufferImage fields + // + OldFRow = HBufferImage.BufferPosition.Row; + OldFCol = HBufferImage.BufferPosition.Column; + OldPos = (OldFRow - 1) * 0x10 + OldFCol - 1; + + // + // move cursor before Pos + // + if (Pos > 0) { + NewPos = Pos - 1; + } else { + NewPos = 0; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + Buffer = AllocateZeroPool (Size + Count); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HBufferImageListToBuffer (Buffer, Size); + + BufferPtr = (UINT8 *) Buffer; + + // + // get a place to add + // + for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) { + BufferPtr[Index] = BufferPtr[Index - Count]; + } + // + // add the buffer + // + for (Index = (INTN) 0; Index < (INTN) Count; Index++) { + BufferPtr[Index + Pos] = AddBuffer[Index]; + } + + Size += Count; + + HBufferImageFreeLines (); + + HBufferImageBufferToList (Buffer, Size); + + FreePool (Buffer); + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + HBufferImage.CurrentLine = Line; + + if (OldPos >= Pos) { + NewPos = OldPos + Count; + } else { + NewPos = OldPos; + } + + HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE); + + return EFI_SUCCESS; +} + +/** + Delete current character from line. + + @retval EFI_SUCCESS The operationw as successful. +**/ +EFI_STATUS +HBufferImageDoDelete ( + VOID + ) +{ + + HEFI_EDITOR_LINE *Line; + + BOOLEAN LastLine; + UINTN FileColumn; + UINTN FPos; + + FPos = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1; + + FileColumn = HBufferImage.BufferPosition.Column; + + Line = HBufferImage.CurrentLine; + + // + // if beyond the last character + // + if (FileColumn > Line->Size) { + return EFI_SUCCESS; + } + + LastLine = FALSE; + if (Line->Link.ForwardLink == HBufferImage.ListHead) { + LastLine = TRUE; + } + + HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL); + + // + // if is the last line + // then only this line need to be refreshed + // + if (LastLine) { + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = TRUE; + } else { + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + } + + if (!HBufferImage.Modified) { + HBufferImage.Modified = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Change the raw buffer to a list of lines for the UI. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageBufferToList ( + IN VOID *Buffer, + IN UINTN Bytes + ) +{ + UINTN TempI; + UINTN TempJ; + UINTN Left; + HEFI_EDITOR_LINE *Line; + UINT8 *BufferPtr; + + TempI = 0; + Left = 0; + BufferPtr = (UINT8 *) Buffer; + + // + // parse file content line by line + // + while (TempI < Bytes) { + if (Bytes - TempI >= 0x10) { + Left = 0x10; + } else { + Left = Bytes - TempI; + } + + // + // allocate a new line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Line->Size = Left; + + for (TempJ = 0; TempJ < Left; TempJ++) { + Line->Buffer[TempJ] = BufferPtr[TempI]; + TempI++; + } + + } + + // + // last line is a full line, SO create a new line + // + if (Left == 0x10 || Bytes == 0) { + Line = HBufferImageCreateLine (); + if (Line == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + return EFI_SUCCESS; +} + +/** + Change the list of lines from the UI to a raw buffer. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageListToBuffer ( + IN VOID *Buffer, + IN UINTN Bytes + ) +{ + UINTN Count; + UINTN Index; + HEFI_EDITOR_LINE *Line; + LIST_ENTRY *Link; + UINT8 *BufferPtr; + + // + // change the line list to a large buffer + // + if (HBufferImage.Lines == NULL) { + return EFI_SUCCESS; + } + + Link = &HBufferImage.Lines->Link; + Count = 0; + BufferPtr = (UINT8 *) Buffer; + + // + // deal line by line + // + while (Link != HBufferImage.ListHead) { + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + //@todo shouldn't this be an error??? + if (Count + Line->Size > Bytes) { + return EFI_SUCCESS; + } + + for (Index = 0; Index < Line->Size; Index++) { + BufferPtr[Index] = Line->Buffer[Index]; + } + + Count += Line->Size; + BufferPtr += Line->Size; + + Link = Link->ForwardLink; + } + + return EFI_SUCCESS; +} + +/** + Move the mouse in the image buffer. + + @param[in] TextX The x-coordinate. + @param[in] TextY The y-coordinate. +**/ +VOID +HBufferImageAdjustMousePosition ( + IN INT32 TextX, + IN INT32 TextY + ) +{ + UINTN TempX; + UINTN TempY; + UINTN AbsX; + UINTN AbsY; + + // + // TextX and TextY is mouse movement data returned by mouse driver + // This function will change it to MousePosition + // + // + // get absolute TempX value + // + if (TextX >= 0) { + AbsX = TextX; + } else { + AbsX = -TextX; + } + // + // get absolute TempY value + // + if (TextY >= 0) { + AbsY = TextY; + } else { + AbsY = -TextY; + } + + TempX = HBufferImage.MousePosition.Column; + TempY = HBufferImage.MousePosition.Row; + + if (TextX >= 0) { + TempX += TextX; + } else { + if (TempX >= AbsX) { + TempX -= AbsX; + } else { + TempX = 0; + } + } + + if (TextY >= 0) { + TempY += TextY; + } else { + if (TempY >= AbsY) { + TempY -= AbsY; + } else { + TempY = 0; + } + } + // + // check whether new mouse column position is beyond screen + // if not, adjust it + // + if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) { + HBufferImage.MousePosition.Column = TempX; + } else if (TempX < 10) { + HBufferImage.MousePosition.Column = 10; + } else if (TempX > (10 + 0x10 * 3 - 1)) { + HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1; + } + // + // check whether new mouse row position is beyond screen + // if not, adjust it + // + if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 1)) { + HBufferImage.MousePosition.Row = TempY; + } else if (TempY < 2) { + HBufferImage.MousePosition.Row = 2; + } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) { + HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1); + } + +} + +/** + Dispatch input to different handler + + @param[in] Key The input key: + the keys can be: + ASCII KEY + Backspace/Delete + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A Memory allocation failed. +**/ +EFI_STATUS +HBufferImageHandleInput ( + IN EFI_INPUT_KEY *Key + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (Key->ScanCode) { + // + // ordinary key + // + case SCAN_NULL: + Status = HBufferImageDoCharInput (Key->UnicodeChar); + break; + + // + // up arrow + // + case SCAN_UP: + Status = HBufferImageScrollUp (); + break; + + // + // down arrow + // + case SCAN_DOWN: + Status = HBufferImageScrollDown (); + break; + + // + // right arrow + // + case SCAN_RIGHT: + Status = HBufferImageScrollRight (); + break; + + // + // left arrow + // + case SCAN_LEFT: + Status = HBufferImageScrollLeft (); + break; + + // + // page up + // + case SCAN_PAGE_UP: + Status = HBufferImagePageUp (); + break; + + // + // page down + // + case SCAN_PAGE_DOWN: + Status = HBufferImagePageDown (); + break; + + // + // delete + // + case SCAN_DELETE: + Status = HBufferImageDoDelete (); + break; + + // + // home + // + case SCAN_HOME: + Status = HBufferImageHome (); + break; + + // + // end + // + case SCAN_END: + Status = HBufferImageEnd (); + break; + + default: + Status = StatusBarSetStatusString (L"Unknown Command"); + break; + } + + return Status; +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h new file mode 100644 index 00000000..082a9cb2 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.h @@ -0,0 +1,267 @@ +/** @file + Defines BufferImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_BUFFER_IMAGE_H_ +#define _LIB_BUFFER_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HBufferImageInit ( + VOID + ); + +/** + Cleanup function for HBufferImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageCleanup ( + VOID + ); + +/** + Refresh function for HBufferImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A Load error occurred. + +**/ +EFI_STATUS +HBufferImageRefresh ( + VOID + ); + +/** + Dispatch input to different handler + + @param[in] Key The input key: + the keys can be: + ASCII KEY + Backspace/Delete + Direction key: up/down/left/right/pgup/pgdn + Home/End + INS + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_OUT_OF_RESOURCES A Memory allocation failed. +**/ +EFI_STATUS +HBufferImageHandleInput ( + IN EFI_INPUT_KEY *Key + ); + +/** + Backup function for HBufferImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageBackup ( + VOID + ); + +/** + Read an image into a buffer friom a source. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + @param[in] Recover TRUE for recovermode, FALSE otherwise. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageRead ( + IN CONST CHAR16 *FileName, + IN CONST CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType, + IN BOOLEAN Recover + ); + +/** + Save the current image. + + @param[in] FileName Pointer to the file name. OPTIONAL and ignored if not FileTypeFileBuffer. + @param[in] DiskName Pointer to the disk name. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskOffset Offset into the disk. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] DiskSize Size of the disk buffer. OPTIONAL and ignored if not FileTypeDiskBuffer. + @param[in] MemOffset Offset into the Memory. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] MemSize Size of the Memory buffer. OPTIONAL and ignored if not FileTypeMemBuffer. + @param[in] BufferType The type of buffer to save. IGNORED. + + @return EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageSave ( + IN CHAR16 *FileName, + IN CHAR16 *DiskName, + IN UINTN DiskOffset, + IN UINTN DiskSize, + IN UINTN MemOffset, + IN UINTN MemSize, + IN EDIT_FILE_TYPE BufferType + ); + +/** + According to cursor's file position, adjust screen display. + + @param[in] NewFilePosRow Row of file position ( start from 1 ). + @param[in] NewFilePosCol Column of file position ( start from 1 ). + @param[in] HighBits Cursor will on high4 bits or low4 bits. +**/ +VOID +HBufferImageMovePosition ( + IN UINTN NewFilePosRow, + IN UINTN NewFilePosCol, + IN BOOLEAN HighBits + ); + + +/** + Create a new line and append it to the line list. + Fields affected: + NumLines + Lines + + @retval NULL create line failed. + @return the line created. + +**/ +HEFI_EDITOR_LINE * +HBufferImageCreateLine ( + VOID + ); + +/** + Free the current image. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageFree ( + VOID + ); + +/** + Delete character from buffer. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count The Count of characters to delete. + @param[out] DeleteBuffer The DeleteBuffer. + + @retval EFI_SUCCESS Success +**/ +EFI_STATUS +HBufferImageDeleteCharacterFromBuffer ( + IN UINTN Pos, + IN UINTN Count, + OUT UINT8 *DeleteBuffer + ); + +/** + Add character to buffer, add before pos. + + @param[in] Pos Position, Pos starting from 0. + @param[in] Count Count of characters to add. + @param[in] AddBuffer Add buffer. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +HBufferImageAddCharacterToBuffer ( + IN UINTN Pos, + IN UINTN Count, + IN UINT8 *AddBuffer + ); + +/** + Change the raw buffer to a list of lines for the UI. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HBufferImageBufferToList ( + IN VOID *Buffer, + IN UINTN Bytes + ); + +/** + Change the list of lines from the UI to a raw buffer. + + @param[in] Buffer The pointer to the buffer to fill. + @param[in] Bytes The size of the buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HBufferImageListToBuffer ( + IN VOID *Buffer, + IN UINTN Bytes + ); + +/** + Move the mouse in the image buffer. + + @param[in] TextX The x-coordinate. + @param[in] TextY The y-coordinate. +**/ +VOID +HBufferImageAdjustMousePosition ( + IN INT32 TextX, + IN INT32 TextY + ); + +/** + Function to decide if a column number is stored in the high bits. + + @param[in] Column The column to examine. + @param[out] FCol The actual column number. + + @retval TRUE The actual column was in high bits and is now in FCol. + @retval FALSE There was not a column number in the high bits. +**/ +BOOLEAN +HBufferImageIsAtHighBits ( + IN UINTN Column, + OUT UINTN *FCol + ); + +/** + Get the size of the open buffer. + + @retval The size in bytes. +**/ +UINTN +HBufferImageGetTotalSize ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c new file mode 100644 index 00000000..5de75a6b --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.c @@ -0,0 +1,106 @@ +/** @file + Functions to deal with Clip Board + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +typedef struct { + UINT8 *Buffer; + UINTN Size; +} HEFI_EDITOR_CLIPBOARD; + +HEFI_EDITOR_CLIPBOARD HClipBoard; + +// +// for basic initialization of HClipBoard +// +HEFI_EDITOR_CLIPBOARD HClipBoardConst = { + NULL, + 0 +}; + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardInit ( + VOID + ) +{ + // + // basiclly initialize the HDiskImage + // + CopyMem (&HClipBoard, &HClipBoardConst, sizeof (HClipBoard)); + + return EFI_SUCCESS; +} + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardCleanup ( + VOID + ) +{ + + SHELL_FREE_NON_NULL (HClipBoard.Buffer); + + return EFI_SUCCESS; +} + +/** + Set a buffer into the clipboard. + + @param[in] Buffer The buffer to add to the clipboard. + @param[in] Size The size of Buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HClipBoardSet ( + IN UINT8 *Buffer, + IN UINTN Size + ) +{ + // + // free the old clipboard buffer + // and set new clipboard buffer + // + SHELL_FREE_NON_NULL (HClipBoard.Buffer); + HClipBoard.Buffer = Buffer; + + HClipBoard.Size = Size; + + return EFI_SUCCESS; +} + +/** + Get a buffer from the clipboard. + + @param[out] Buffer The pointer to the buffer to add to the clipboard. + + @return the size of the buffer. +**/ +UINTN +HClipBoardGet ( + OUT UINT8 **Buffer + ) +{ + // + // return the clipboard buffer + // + *Buffer = HClipBoard.Buffer; + + return HClipBoard.Size; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h new file mode 100644 index 00000000..6408ae0e --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Clipboard.h @@ -0,0 +1,63 @@ +/** @file + Defines DiskImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_CLIP_BOARD_H_ +#define _LIB_CLIP_BOARD_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardInit ( + VOID + ); + +/** + Initialization function for HDiskImage. + + @param[in] EFI_SUCCESS The operation was successful. + @param[in] EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HClipBoardCleanup ( + VOID + ); + +/** + Set a buffer into the clipboard. + + @param[in] Buffer The buffer to add to the clipboard. + @param[in] Size The size of Buffer in bytes. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HClipBoardSet ( + IN UINT8 *Buffer, + IN UINTN Size + ); + +/** + Get a buffer from the clipboard. + + @param[out] Buffer The pointer to the buffer to add to the clipboard. + + @return the size of the buffer. +**/ +UINTN +HClipBoardGet ( + OUT UINT8 **Buffer + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c new file mode 100644 index 00000000..80f614c6 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.c @@ -0,0 +1,411 @@ +/** @file + Functions to deal with Disk buffer. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" +#include <Protocol/BlockIo.h> + +extern EFI_HANDLE HImageHandleBackup; +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_DISK_IMAGE HDiskImage; +HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar; + +// +// for basic initialization of HDiskImage +// +HEFI_EDITOR_DISK_IMAGE HDiskImageConst = { + NULL, + 0, + 0, + 0 +}; + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HDiskImageInit ( + VOID + ) +{ + // + // basically initialize the HDiskImage + // + CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage)); + + CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar)); + + return EFI_SUCCESS; +} + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources. +**/ +EFI_STATUS +HDiskImageBackup ( + VOID + ) +{ + // + // backup the disk name, offset and size + // + // + SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name); + + HDiskImageBackupVar.Name = CatSPrint(NULL, L"%s", HDiskImage.Name); + if (HDiskImageBackupVar.Name == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HDiskImageBackupVar.Offset = HDiskImage.Offset; + HDiskImageBackupVar.Size = HDiskImage.Size; + + return EFI_SUCCESS; +} + +/** + Cleanup function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HDiskImageCleanup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HDiskImage.Name); + SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name); + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage. + + @param[in] Str File name to set. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HDiskImageSetDiskNameOffsetSize ( + IN CONST CHAR16 *Str, + IN UINTN Offset, + IN UINTN Size + ) +{ + if (Str == HDiskImage.Name) { + // + // This function might be called using HDiskImage.FileName as Str. + // Directly return without updating HDiskImage.FileName. + // + return EFI_SUCCESS; + } + + // + // free the old file name + // + SHELL_FREE_NON_NULL (HDiskImage.Name); + HDiskImage.Name = AllocateCopyPool (StrSize (Str), Str); + if (HDiskImage.Name == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HDiskImage.Offset = Offset; + HDiskImage.Size = Size; + + return EFI_SUCCESS; +} + +/** + Read a disk from disk into HBufferImage. + + @param[in] DeviceName filename to read. + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageRead ( + IN CONST CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ) +{ + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; + EFI_HANDLE Handle; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_STATUS Status; + + VOID *Buffer; + CHAR16 *Str; + UINTN Bytes; + + HEFI_EDITOR_LINE *Line; + + HBufferImage.BufferType = FileTypeDiskBuffer; + + DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName); + if (DevicePath == NULL) { + StatusBarSetStatusString (L"Cannot Find Device"); + return EFI_INVALID_PARAMETER; + } + DupDevicePath = DuplicateDevicePath(DevicePath); + DupDevicePathForFree = DupDevicePath; + // + // get blkio interface + // + Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle); + FreePool(DupDevicePathForFree); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + // + // if Offset exceeds LastBlock, + // return error + // + if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) { + StatusBarSetStatusString (L"Invalid Offset + Size"); + return EFI_LOAD_ERROR; + } + + Bytes = BlkIo->Media->BlockSize * Size; + Buffer = AllocateZeroPool (Bytes); + + if (Buffer == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + // + // read from disk + // + Status = BlkIo->ReadBlocks ( + BlkIo, + BlkIo->Media->MediaId, + Offset, + Bytes, + Buffer + ); + + if (EFI_ERROR (Status)) { + FreePool (Buffer); + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_LOAD_ERROR; + } + + HBufferImageFree (); + + // + // convert buffer to line list + // + Status = HBufferImageBufferToList (Buffer, Bytes); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + // + // initialize some variables + // + HDiskImage.BlockSize = BlkIo->Media->BlockSize; + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + + if (!Recover) { + Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); + if (Str == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (Str); + SHELL_FREE_NON_NULL (Str); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + + } + + // + // has line + // + if (HBufferImage.Lines != NULL) { + HBufferImage.CurrentLine = CR ( + HBufferImage.ListHead->ForwardLink, + HEFI_EDITOR_LINE, + Link, + EFI_EDITOR_LINE_LIST + ); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + StatusBarSetStatusString (L"Read Disk Failed"); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save lines in HBufferImage to disk. + NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! + + @param[in] DeviceName The device name. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageSave ( + IN CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size + ) +{ + + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_STATUS Status; + EFI_HANDLE Handle; + VOID *Buffer; + UINTN Bytes; + + // + // if not modified, directly return + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + + HBufferImage.BufferType = FileTypeDiskBuffer; + + DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName); + if (DevicePath == NULL) { +// StatusBarSetStatusString (L"Cannot Find Device"); + return EFI_INVALID_PARAMETER; + } + DupDevicePath = DuplicateDevicePath(DevicePath); + DupDevicePathForFree = DupDevicePath; + + // + // get blkio interface + // + Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle); + FreePool(DupDevicePathForFree); + if (EFI_ERROR (Status)) { +// StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { +// StatusBarSetStatusString (L"Read Disk Failed"); + return Status; + } + + Bytes = BlkIo->Media->BlockSize * Size; + Buffer = AllocateZeroPool (Bytes); + + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // concatenate the line list to a buffer + // + Status = HBufferImageListToBuffer (Buffer, Bytes); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + // + // write the buffer to disk + // + Status = BlkIo->WriteBlocks ( + BlkIo, + BlkIo->Media->MediaId, + Offset, + Bytes, + Buffer + ); + + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + // + // now not modified + // + HBufferImage.Modified = FALSE; + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h new file mode 100644 index 00000000..dd1f4760 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/DiskImage.h @@ -0,0 +1,89 @@ +/** @file + Defines DiskImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_DISK_IMAGE_H_ +#define _LIB_DISK_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HDiskImageInit ( + VOID + ); + +/** + Cleanup function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HDiskImageCleanup ( + VOID + ); + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources. +**/ +EFI_STATUS +HDiskImageBackup ( + VOID + ); + +/** + Read a disk from disk into HBufferImage. + + @param[in] DeviceName filename to read. + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageRead ( + IN CONST CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!! + + @param[in] DeviceName The device name. + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_INVALID_PARAMETER A parameter was invalid. +**/ +EFI_STATUS +HDiskImageSave ( + IN CHAR16 *DeviceName, + IN UINTN Offset, + IN UINTN Size + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c new file mode 100644 index 00000000..01fb554d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.c @@ -0,0 +1,392 @@ +/** @file + Functions to deal with file buffer. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_FILE_IMAGE HFileImage; +HEFI_EDITOR_FILE_IMAGE HFileImageBackupVar; + +// +// for basic initialization of HFileImage +// +HEFI_EDITOR_BUFFER_IMAGE HFileImageConst = { + NULL, + 0, + FALSE +}; + +/** + Initialization function for HFileImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageInit ( + VOID + ) +{ + // + // basically initialize the HFileImage + // + CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage)); + + CopyMem ( + &HFileImageBackupVar, + &HFileImageConst, + sizeof (HFileImageBackupVar) + ); + + return EFI_SUCCESS; +} + +/** + Backup function for HFileImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageBackup ( + VOID + ) +{ + SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName); + HFileImageBackupVar.FileName = CatSPrint(NULL, L"%s", HFileImage.FileName); + if (HFileImageBackupVar.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Cleanup function for HFileImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageCleanup ( + VOID + ) +{ + + SHELL_FREE_NON_NULL (HFileImage.FileName); + SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName); + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage + + @param[in] Str File name to set. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageSetFileName ( + IN CONST CHAR16 *Str + ) +{ + if (Str == HFileImage.FileName) { + // + // This function might be called using HFileImage.FileName as Str. + // Directly return without updating HFileImage.FileName. + // + return EFI_SUCCESS; + } + // + // free the old file name + // + SHELL_FREE_NON_NULL (HFileImage.FileName); + HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str); + if (HFileImage.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Read a file from disk into HBufferImage. + + @param[in] FileName filename to read. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageRead ( + IN CONST CHAR16 *FileName, + IN BOOLEAN Recover + ) +{ + HEFI_EDITOR_LINE *Line; + UINT8 *Buffer; + CHAR16 *UnicodeBuffer; + EFI_STATUS Status; + + // + // variable initialization + // + Line = NULL; + + // + // in this function, when you return error ( except EFI_OUT_OF_RESOURCES ) + // you should set status string + // since this function maybe called before the editorhandleinput loop + // so any error will cause editor return + // so if you want to print the error status + // you should set the status string + // + Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly); + // + // NULL pointer is only also a failure for a non-zero file size. + // + if ((EFI_ERROR(Status)) || (Buffer == NULL && HFileImage.Size != 0)) { + UnicodeBuffer = CatSPrint(NULL, L"Read error on file %s: %r", FileName, Status); + if (UnicodeBuffer == NULL) { + SHELL_FREE_NON_NULL(Buffer); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (UnicodeBuffer); + FreePool (UnicodeBuffer); + return EFI_OUT_OF_RESOURCES; + } + + HFileImageSetFileName (FileName); + + // + // free the old lines + // + HBufferImageFree (); + + Status = HBufferImageBufferToList (Buffer, HFileImage.Size); + SHELL_FREE_NON_NULL (Buffer); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Error parsing file."); + return Status; + } + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + HBufferImage.BufferType = FileTypeFileBuffer; + + if (!Recover) { + UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); + if (UnicodeBuffer == NULL) { + SHELL_FREE_NON_NULL(Buffer); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (UnicodeBuffer); + FreePool (UnicodeBuffer); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + } + + // + // has line + // + if (HBufferImage.Lines != 0) { + HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + SHELL_FREE_NON_NULL(Buffer); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save lines in HBufferImage to disk. + + @param[in] FileName The file name. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageSave ( + IN CHAR16 *FileName + ) +{ + + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + CHAR16 *Str; + EFI_STATUS Status; + UINTN NumLines; + SHELL_FILE_HANDLE FileHandle; + UINTN TotalSize; + UINT8 *Buffer; + UINT8 *Ptr; + EDIT_FILE_TYPE BufferTypeBackup; + + BufferTypeBackup = HBufferImage.BufferType; + HBufferImage.BufferType = FileTypeFileBuffer; + + // + // if is the old file + // + if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) { + // + // check whether file exists on disk + // + if (ShellIsFile(FileName) == EFI_SUCCESS) { + // + // current file exists on disk + // so if not modified, then not save + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + // + // if file is read-only, set error + // + if (HFileImage.ReadOnly == TRUE) { + StatusBarSetStatusString (L"Read Only File Can Not Be Saved"); + return EFI_SUCCESS; + } + } + } + + if (ShellIsDirectory(FileName) == EFI_SUCCESS) { + StatusBarSetStatusString (L"Directory Can Not Be Saved"); + return EFI_LOAD_ERROR; + } + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); + + if (!EFI_ERROR (Status)) { + // + // the file exits, delete it + // + Status = ShellDeleteFile (&FileHandle); + if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) { + StatusBarSetStatusString (L"Write File Failed"); + return EFI_LOAD_ERROR; + } + } + + // + // write all the lines back to disk + // + NumLines = 0; + TotalSize = 0; + for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + if (Line->Size != 0) { + TotalSize += Line->Size; + } + // + // end of if Line -> Size != 0 + // + NumLines++; + } + // + // end of for Link + // + Buffer = AllocateZeroPool (TotalSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr = Buffer; + for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + if (Line->Size != 0) { + CopyMem (Ptr, Line->Buffer, Line->Size); + Ptr += Line->Size; + } + // + // end of if Line -> Size != 0 + // + } + + + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Create File Failed"); + return EFI_LOAD_ERROR; + } + + Status = ShellWriteFile (FileHandle, &TotalSize, Buffer); + FreePool (Buffer); + if (EFI_ERROR (Status)) { + ShellDeleteFile (&FileHandle); + return EFI_LOAD_ERROR; + } + + ShellCloseFile(&FileHandle); + + HBufferImage.Modified = FALSE; + + // + // set status string + // + Str = CatSPrint(NULL, L"%d Lines Written", NumLines); + StatusBarSetStatusString (Str); + FreePool (Str); + + // + // now everything is ready , you can set the new file name to filebuffer + // + if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) || + (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){ + // + // not the same + // + HFileImageSetFileName (FileName); + if (HFileImage.FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + HFileImage.ReadOnly = FALSE; + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h new file mode 100644 index 00000000..9472b343 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/FileImage.h @@ -0,0 +1,77 @@ +/** @file + Defines FileImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_FILE_IMAGE_H_ +#define _LIB_FILE_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HFileImage + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageInit ( + VOID + ); + +/** + Cleanup function for HFileImage. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFileImageCleanup ( + VOID + ); + +/** + Backup function for HFileImage. Only a few fields need to be backup. + This is for making the file buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HFileImageBackup ( + VOID + ); + +/** + Read a file from disk into HBufferImage. + + @param[in] FileName filename to read. + @param[in] Recover if is for recover, no information print. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageRead ( + IN CONST CHAR16 *FileName, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + + @param[in] FileName The file name. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HFileImageSave ( + IN CHAR16 *FileName + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c new file mode 100644 index 00000000..ac1bc22b --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEdit.c @@ -0,0 +1,271 @@ +/** @file + Main entry point of editor + + (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "HexEditor.h" + +// +// Global Variables +// +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-f", TypeFlag}, + {L"-d", TypeFlag}, + {L"-m", TypeFlag}, + {NULL, TypeMax} + }; + +/** + Function for 'hexedit' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunHexEdit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CHAR16 *Buffer; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + LIST_ENTRY *Package; + CHAR16 *NewName; + CONST CHAR16 *Name; + UINTN Offset; + UINTN Size; + EDIT_FILE_TYPE WhatToDo; + + Buffer = NULL; + ShellStatus = SHELL_SUCCESS; + NewName = NULL; + Buffer = NULL; + Name = NULL; + Offset = 0; + Size = 0; + WhatToDo = FileTypeNone; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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), gShellDebug1HiiHandle, L"hexedit", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + // + // Check for -d + // + if (ShellCommandLineGetFlag(Package, L"-d")){ + if (ShellCommandLineGetCount(Package) < 4) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) > 4) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeDiskBuffer; + Name = ShellCommandLineGetRawValue(Package, 1); + Offset = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2)); + Size = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 3)); + } + if (Offset == (UINTN)-1 || Size == (UINTN)-1) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"hexedit", L"-d"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + + // + // check for -f + // + if (ShellCommandLineGetFlag(Package, L"-f") && (WhatToDo == FileTypeNone)){ + if (ShellCommandLineGetCount(Package) < 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) > 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Name = ShellCommandLineGetRawValue(Package, 1); + if (Name == NULL || !IsValidFileName(Name)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeFileBuffer; + } + } + } + + // + // check for -m + // + if (ShellCommandLineGetFlag(Package, L"-m") && (WhatToDo == FileTypeNone)){ + if (ShellCommandLineGetCount(Package) < 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeMemBuffer; + Offset = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 1)); + Size = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2)); + } + } + Name = ShellCommandLineGetRawValue(Package, 1); + if (WhatToDo == FileTypeNone && Name != NULL) { + if (ShellCommandLineGetCount(Package) > 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (!IsValidFileName(Name)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + WhatToDo = FileTypeFileBuffer; + } + } else if (WhatToDo == FileTypeNone) { + if (gEfiShellProtocol->GetCurDir(NULL) == NULL) { + ShellStatus = SHELL_NOT_FOUND; + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); + } else { + NewName = EditGetDefaultFileName(L"bin"); + Name = NewName; + WhatToDo = FileTypeFileBuffer; + } + } + + if (ShellStatus == SHELL_SUCCESS && WhatToDo == FileTypeNone) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (WhatToDo == FileTypeFileBuffer && ShellGetCurrentDir(NULL) == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + + if (ShellStatus == SHELL_SUCCESS) { + // + // Do the editor + // + Status = HMainEditorInit (); + if (EFI_ERROR (Status)) { + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_INIT_FAILED), gShellDebug1HiiHandle); + } else { + HMainEditorBackup (); + switch (WhatToDo) { + case FileTypeFileBuffer: + Status = HBufferImageRead ( + Name==NULL?L"":Name, + NULL, + 0, + 0, + 0, + 0, + FileTypeFileBuffer, + FALSE + ); + break; + + case FileTypeDiskBuffer: + Status = HBufferImageRead ( + NULL, + Name==NULL?L"":Name, + Offset, + Size, + 0, + 0, + FileTypeDiskBuffer, + FALSE + ); + break; + + case FileTypeMemBuffer: + Status = HBufferImageRead ( + NULL, + NULL, + 0, + 0, + (UINT32) Offset, + Size, + FileTypeMemBuffer, + FALSE + ); + break; + + default: + Status = EFI_NOT_FOUND; + break; + } + if (!EFI_ERROR (Status)) { + HMainEditorRefresh (); + Status = HMainEditorKeyInput (); + } + if (Status != EFI_OUT_OF_RESOURCES) { + // + // back up the status string + // + Buffer = CatSPrint (NULL, L"%s\r\n", StatusBarGetString()); + } + } + + // + // cleanup + // + HMainEditorCleanup (); + + if (EFI_ERROR (Status)) { + if (ShellStatus == SHELL_SUCCESS) { + ShellStatus = SHELL_UNSUPPORTED; + } + } + + // + // print editor exit code on screen + // + if (Status == EFI_OUT_OF_RESOURCES) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"hexedit"); + } else if (EFI_ERROR(Status)){ + if (Buffer != NULL) { + if (StrCmp (Buffer, L"") != 0) { + // + // print out the status string + // + ShellPrintEx(-1, -1, L"%s", Buffer); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); + } + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); + } + } + } + ShellCommandLineFreeVarList (Package); + } + + SHELL_FREE_NON_NULL (Buffer); + SHELL_FREE_NON_NULL (NewName); + return ShellStatus; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h new file mode 100644 index 00000000..e68937ea --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditor.h @@ -0,0 +1,35 @@ +/** @file + Main include file for hex editor + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_SHELL_HEXEDIT_H_ +#define _EFI_SHELL_HEXEDIT_H_ + +#include "UefiShellDebug1CommandsLib.h" +#include "HexEditorTypes.h" + +#include "MainHexEditor.h" + +#include "BufferImage.h" +#include "FileImage.h" +#include "DiskImage.h" +#include "MemImage.h" + +#include "EditTitleBar.h" +#include "EditStatusBar.h" +#include "EditInputBar.h" +#include "EditMenuBar.h" + +#include "Misc.h" + +#include "Clipboard.h" + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; +extern BOOLEAN HEditorFirst; +extern BOOLEAN HEditorExit; + +#endif // _HEDITOR_H diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h new file mode 100644 index 00000000..3ac8432b --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes.h @@ -0,0 +1,120 @@ +/** @file + data types that are used by editor + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _HEDITOR_TYPE_H_ +#define _HEDITOR_TYPE_H_ + +#include "UefiShellDebug1CommandsLib.h" +#include "EditTitleBar.h" + +#define EFI_EDITOR_LINE_LIST SIGNATURE_32 ('e', 'e', 'l', 'l') + +#define ASCII_POSITION ((0x10 * 3) + 12) + + +typedef struct { + UINTN Row; + UINTN Column; +} HEFI_EDITOR_POSITION; + +typedef +EFI_STATUS +(*HEFI_MENU_ITEM_FUNCTION) ( + VOID + ); + +typedef struct { + CHAR16 Name[50]; + CHAR16 Key[3]; + HEFI_MENU_ITEM_FUNCTION Function; +} HMENU_ITEMS; + +typedef struct _HEFI_EDITOR_LINE { + UINTN Signature; + UINT8 Buffer[0x10]; + UINTN Size; // unit is Unicode + LIST_ENTRY Link; +} HEFI_EDITOR_LINE; + +typedef struct _HEFI_EDITOR_MENU_ITEM { + CHAR16 NameToken; + CHAR16 FunctionKeyToken; + HEFI_MENU_ITEM_FUNCTION Function; +} HEFI_EDITOR_MENU_ITEM; + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 4; +} HEFI_EDITOR_COLOR_ATTRIBUTES; + +typedef union { + HEFI_EDITOR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} HEFI_EDITOR_COLOR_UNION; + +typedef struct { + UINTN Columns; + UINTN Rows; +} HEFI_EDITOR_TEXT_MODE; + + +typedef struct { + CHAR16 *Name; + + UINTN BlockSize; + UINTN Size; + UINTN Offset; +} HEFI_EDITOR_DISK_IMAGE; + +typedef struct { + EFI_CPU_IO2_PROTOCOL *IoFncs; + UINTN Offset; + UINTN Size; +} HEFI_EDITOR_MEM_IMAGE; + +typedef struct { + CHAR16 *FileName; + UINTN Size; // file size + BOOLEAN ReadOnly; // file is read-only or not +} HEFI_EDITOR_FILE_IMAGE; + +typedef struct { + LIST_ENTRY *ListHead; // list head of lines + HEFI_EDITOR_LINE *Lines; // lines of current file + UINTN NumLines; // number of lines + HEFI_EDITOR_LINE *CurrentLine; // current line cursor is at + HEFI_EDITOR_POSITION DisplayPosition; // cursor position in screen + HEFI_EDITOR_POSITION MousePosition; // mouse position in screen + HEFI_EDITOR_POSITION BufferPosition; // cursor position in buffer + UINTN LowVisibleRow; // the lowest visible row of file position + BOOLEAN HighBits; // cursor is at the high4 bits or low4 bits + BOOLEAN Modified; // BUFFER is modified or not + EDIT_FILE_TYPE BufferType; + + HEFI_EDITOR_FILE_IMAGE *FileImage; + HEFI_EDITOR_DISK_IMAGE *DiskImage; + HEFI_EDITOR_MEM_IMAGE *MemImage; + +} HEFI_EDITOR_BUFFER_IMAGE; + +typedef struct { + HEFI_EDITOR_BUFFER_IMAGE *BufferImage; + + HEFI_EDITOR_COLOR_UNION ColorAttributes; + HEFI_EDITOR_POSITION ScreenSize; // row number and column number + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; + BOOLEAN MouseSupported; + EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; + INT32 MouseAccumulatorX; + INT32 MouseAccumulatorY; + + UINTN SelectStart; // starting from 1 + UINTN SelectEnd; // starting from 1 +} HEFI_EDITOR_GLOBAL_EDITOR; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni new file mode 100644 index 00000000..65d342fb --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexeditStrings.uni @@ -0,0 +1,70 @@ +// /**
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Abstract:
+//
+// Additional string definitions for UEFI Shell 2.0 Debug1 profile Edit command
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "english"
+
+
+#string STR_HEXEDIT_USAGE #language en-US "\n\n %EHexEditor Usage%N\n"
+#string STR_HEXEDIT_FILENAME #language en-US " %H[-f] Filename%N Open File For Editing\n"
+#string STR_HEXEDIT_DISKNAME #language en-US " %H-d DiskName FirstBlockNo. BlockNumber%N Open Disk Block For Editing\n"
+#string STR_HEXEDIT_OFFSET_SIZE #language en-US " %H-m Offset Size%N Open Memory Region For Editing\n"
+#string STR_HEXEDIT_FILE_NAME #language en-US "%Hhexedit%N: Invalid File Name\n"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE #language en-US "%EMainEditor init failed on TitleBar init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU #language en-US "%EMainEditor init failed on MainMenu init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS #language en-US "%EMainEditor init failed on StatusBar init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_INPUTBAR #language en-US "%EMainEditor init failed on InputBar init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE #language en-US "%EMainEditor init failed on BufferImage init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD #language en-US "%EMainEditor init failed on ClipBoard init\n%N"
+#string STR_HEXEDIT_LIBEDITOR_TITLEBAR_CLEAN #language en-US "TitleBar cleanup failed\n"
+#string STR_HEXEDIT_LIBEDITOR_MENUBAR_CLEAN #language en-US "MenuBar cleanup failed\n"
+#string STR_HEXEDIT_LIBEDITOR_STATUSBAR_CLEAN #language en-US "StatusBar cleanup failed\n"
+#string STR_HEXEDIT_LIBEDITOR_INPUTBAR_CLEAN #language en-US "InputBar cleanup failed\n"
+#string STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN #language en-US "BufferImage cleanup failed\n"
+#string STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN #language en-US "ClipBoard cleanup failed\n"
+#string STR_HEXEDIT_LIBINPUTBAR_MAININPUTBAR #language en-US "%s"
+#string STR_HEXEDIT_LIBMENUBAR_OPEN_FILE #language en-US "Open File"
+#string STR_HEXEDIT_LIBMENUBAR_OPEN_DISK #language en-US "Open Disk"
+#string STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY #language en-US "Open Memory"
+#string STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER #language en-US "Save Buffer"
+#string STR_HEXEDIT_LIBMENUBAR_SELECT_START #language en-US "Select Start"
+#string STR_HEXEDIT_LIBMENUBAR_SELECT_END #language en-US "Select End"
+#string STR_HEXEDIT_LIBMENUBAR_CUT #language en-US "Cut"
+#string STR_HEXEDIT_LIBMENUBAR_PASTE #language en-US "Paste"
+#string STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET #language en-US "Go To Offset"
+#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR #language en-US "%s"
+#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_C #language en-US "%c"
+#string STR_HEXEDIT_LIBTITLEBAR_MAINEDITOR_TWOVARS #language en-US "( %X ~ %X ) "
+#string STR_HEXEDIT_LIBTITLEBAR_FILE #language en-US " [FILE]"
+#string STR_HEXEDIT_LIBTITLEBAR_DISK #language en-US " [DISK]"
+#string STR_HEXEDIT_LIBTITLEBAR_MEM #language en-US " [MEM]"
+#string STR_HEXEDIT_HELP_TITLE #language en-US "Help \n"
+#string STR_HEXEDIT_HELP_BLANK #language en-US " \n"
+#string STR_HEXEDIT_HELP_LIST_TITLE #language en-US "Control Key Function Key Command \n"
+#string STR_HEXEDIT_HELP_DIV #language en-US "----------- ------------ ----------------- \n"
+#string STR_HEXEDIT_HELP_GO_TO_OFFSET #language en-US "Ctrl-G F1 Go To Offset \n"
+#string STR_HEXEDIT_HELP_SAVE_BUFFER #language en-US "Ctrl-S F2 Save Buffer \n"
+#string STR_HEXEDIT_HELP_EXIT #language en-US "Ctrl-Q F3 Exit \n"
+#string STR_HEXEDIT_HELP_SELECT_START #language en-US "Ctrl-T F4 Select Start \n"
+#string STR_HEXEDIT_HELP_SELECT_END #language en-US "Ctrl-D F5 Select End \n"
+#string STR_HEXEDIT_HELP_CUT #language en-US "Ctrl-X F6 Cut \n"
+#string STR_HEXEDIT_HELP_PASTE #language en-US "Ctrl-V F7 Paste \n"
+#string STR_HEXEDIT_HELP_OPEN_FILE #language en-US "Ctrl-O F8 Open File \n"
+#string STR_HEXEDIT_HELP_OPEN_DISK #language en-US "Ctrl-I F9 Open Disk \n"
+#string STR_HEXEDIT_HELP_OPEN_MEMORY #language en-US "Ctrl-M F10 Open Memory \n"
+#string STR_HEXEDIT_HELP_EXIT_HELP #language en-US "Use Ctrl-W to exit this help \n"
+#string STR_HEXEDIT_INIT_FAILED #language en-US "%Hhexedit%N: Initialization failed\n"
+#string STR_HEXEDIT_ONE_VAR #language en-US "%Hhexedit%N: %s\n"
+#string STR_HEXEDIT_UNKNOWN_EDITOR #language en-US "%Hhexedit%N: Unknown editor error\n"
+#string STR_HEXEDIT_NOREDIRECT #language en-US "%Hhexedit%N: Redirection is not allowed\n"
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c new file mode 100644 index 00000000..43e99ba3 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c @@ -0,0 +1,2372 @@ +/** @file + Defines the Main Editor data type - + - Global variables + - Instances of the other objects of the editor + - Main Interfaces + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" +#include "EditStatusBar.h" +#include "EditInputBar.h" + +HEFI_EDITOR_COLOR_ATTRIBUTES HOriginalColors; +INTN HOriginalMode; + +// +// the first time editor launch +// +BOOLEAN HEditorFirst; + +// +// it's time editor should exit +// +BOOLEAN HEditorExit; + +BOOLEAN HEditorMouseAction; + +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar; + +extern BOOLEAN HBufferImageMouseNeedRefresh; +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; + +HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; +HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar; + +// +// basic initialization for MainEditor +// +HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = { + &HBufferImage, + { + {0, 0} + }, + { + 0, + 0 + }, + NULL, + FALSE, + NULL, + 0, + 0, + 1, + 1 +}; + +/** + Help info that will be displayed. +**/ +EFI_STRING_ID HexMainMenuHelpInfo[] = { + STRING_TOKEN(STR_HEXEDIT_HELP_TITLE), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_LIST_TITLE), + STRING_TOKEN(STR_HEXEDIT_HELP_DIV), + STRING_TOKEN(STR_HEXEDIT_HELP_GO_TO_OFFSET), + STRING_TOKEN(STR_HEXEDIT_HELP_SAVE_BUFFER), + STRING_TOKEN(STR_HEXEDIT_HELP_EXIT), + STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_START), + STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_END), + STRING_TOKEN(STR_HEXEDIT_HELP_CUT), + STRING_TOKEN(STR_HEXEDIT_HELP_PASTE), + STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_FILE), + STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_DISK), + STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_MEMORY), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_EXIT_HELP), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_BLANK), + STRING_TOKEN(STR_HEXEDIT_HELP_DIV), + 0 +}; + + +/** + show help menu. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMainCommandDisplayHelp ( + VOID + ) +{ + INT32 CurrentLine; + CHAR16 *InfoString; + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + UINTN EventIndex; + + // + // print helpInfo + // + for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) { + InfoString = HiiGetString(gShellDebug1HiiHandle, HexMainMenuHelpInfo[CurrentLine] +, NULL); + ShellPrintEx (0,CurrentLine+1,L"%E%s%N",InfoString); + } + + // + // scan for ctrl+w + // + while (TRUE) { + Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex); + if (EFI_ERROR (Status) || (EventIndex != 0)) { + continue; + } + Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData); + if (EFI_ERROR (Status)) { + continue; + } + + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || + (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) { + // + // For consoles that don't support/report shift state, + // CTRL+W is translated to L'W' - L'A' + 1. + // + if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) { + break; + } + } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && + ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) && + ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) { + // + // For consoles that supports/reports shift state, + // make sure that only CONTROL shift key is pressed. + // + if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) { + break; + } + } + } + + // update screen with buffer's info + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageRefresh (); + + return EFI_SUCCESS; +} + +/** + Move cursor to specified lines. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMainCommandGoToOffset ( + VOID + ) +{ + UINTN Size; + UINT64 Offset; + EFI_STATUS Status; + UINTN FRow; + UINTN FCol; + + // + // variable initialization + // + Size = 0; + Offset = 0; + FRow = 0; + FCol = 0; + + // + // get offset + // + Status = InputBarSetPrompt (L"Go To Offset: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (8); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE); + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Invalid Offset"); + return EFI_SUCCESS; + } + + break; + } + } + + Size = HBufferImageGetTotalSize (); + if (Offset >= Size) { + StatusBarSetStatusString (L"Invalid Offset"); + return EFI_SUCCESS; + } + + FRow = (UINTN)DivU64x32(Offset , 0x10) + 1; + FCol = (UINTN)ModU64x32(Offset , 0x10) + 1; + + HBufferImageMovePosition (FRow, FCol, TRUE); + + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Save current opened buffer. + If is file buffer, you can save to current file name or + save to another file name. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandSaveBuffer ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN Done; + CHAR16 *FileName; + BOOLEAN OldFile; + CHAR16 *Str; + EFI_FILE_INFO *Info; + SHELL_FILE_HANDLE ShellFileHandle; + + if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) { + if (!HMainEditor.BufferImage->Modified) { + return EFI_SUCCESS; + } + + Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // the answer is just one character + // + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + // + // loop for user's answer + // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' + // + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // want to save this buffer first + // + Status = HBufferImageSave ( + NULL, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + HMainEditor.BufferImage->BufferType + ); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"BufferSave: Problems Writing"); + return Status; + } + + return EFI_SUCCESS; + + case L'n': + case L'N': + // + // the file won't be saved + // + return EFI_SUCCESS; + + case L'c': + case L'C': + return EFI_SUCCESS; + } + // + // end of switch + // + } + // + // ENDOF WHILE + // + } + // + // ENDOF != FILEBUFFER + // + // This command will save currently opened file to disk. + // You can choose save to another file name or just save to + // current file name. + // Below is the scenario of Save File command: ( + // Suppose the old file name is A ) + // 1. An Input Bar will be prompted: "File To Save: [ old file name]" + // IF user press ESC, Save File command ends . + // IF user press Enter, input file name will be A. + // IF user inputs a new file name B, input file name will be B. + // + // 2. IF input file name is A, go to do Step 3. + // IF input file name is B, go to do Step 4. + // + // 3. IF A is read only, Status Bar will show "Access Denied" + // and Save File commands ends. + // IF A is not read only, save file buffer to disk + // and remove Modified flag in Title Bar , then Save File command ends. + // + // 4. IF B does not exist, create this file and save file buffer to it. + // Go to do Step 7. + // IF B exits, do Step 5. + // + // 5. An Input Bar will be prompted: + // "File Exists. Overwrite ( Yes/No/Cancel ) ?" + // IF user press 'y' or 'Y', do Step 6. + // IF user press 'n' or 'N', Save File commands ends. + // IF user press 'c' or 'C' or ESC, Save File commands ends. + // + // 6. IF B is a read-only file, Status Bar will show "Access Denied" + // and Save File commands ends. + // IF B can be read and write, save file buffer to B. + // + // 7. Update File Name field in Title Bar to B + // and remove the Modified flag in Title Bar. + // + Str = CatSPrint(NULL, + L"File to Save: [%s]", + HMainEditor.BufferImage->FileImage->FileName + ); + if (Str == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (StrLen (Str) >= 50) { + // + // replace the long file name with "..." + // + Str[46] = L'.'; + Str[47] = L'.'; + Str[48] = L'.'; + Str[49] = L']'; + Str[50] = L'\0'; + } + + Status = InputBarSetPrompt (Str); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (100); + if (EFI_ERROR (Status)) { + return Status; + } + // + // get new file name + // + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // if user pressed ESC + // + if (Status == EFI_NOT_READY) { + SHELL_FREE_NON_NULL (Str); + return EFI_SUCCESS; + } + + SHELL_FREE_NON_NULL (Str); + + // + // if just enter pressed, so think save to current file name + // + if (StrLen (InputBarGetString()) == 0) { + FileName = CatSPrint(NULL, + L"%s", + HMainEditor.BufferImage->FileImage->FileName + ); + } else { + FileName = CatSPrint(NULL, L"%s", InputBarGetString()); + } + + if (FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (!IsValidFileName (FileName)) { + StatusBarSetStatusString (L"Invalid File Name"); + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } + + OldFile = FALSE; + + // + // save to the old file + // + if (StringNoCaseCompare ( + &FileName, + &HMainEditor.BufferImage->FileImage->FileName + ) == 0) { + OldFile = TRUE; + } + + if (OldFile) { + // + // if the file is read only, so can not write back to it. + // + if (HMainEditor.BufferImage->FileImage->ReadOnly) { + StatusBarSetStatusString (L"Access Denied"); + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } + } else { + Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0); + + if (!EFI_ERROR (Status)) { + + Info = ShellGetFileInfo(ShellFileHandle); + + ShellCloseFile(&ShellFileHandle); + // + // check if read only + // + if (Info->Attribute & EFI_FILE_READ_ONLY) { + StatusBarSetStatusString (L"Access Denied"); + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } + + SHELL_FREE_NON_NULL(Info); + // + // ask user whether to overwrite this file + // + Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (FileName); + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (FileName); + return Status; + } + + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + if (Status == EFI_NOT_READY) { + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + Done = TRUE; + break; + case L'n': + case L'N': + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + case L'c': + case L'C': + SHELL_FREE_NON_NULL (FileName); + return EFI_SUCCESS; + } // switch + } // while + } // if opened existing file + } // if OldFile + + // + // save file back to disk + // + Status = HBufferImageSave ( + FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + FileTypeFileBuffer + ); + SHELL_FREE_NON_NULL (FileName); + + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Load a disk buffer editor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandSelectStart ( + VOID + ) +{ + UINTN Start; + + Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column; + + // + // last line + // + if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { + if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) { + StatusBarSetStatusString (L"Invalid Block Start"); + return EFI_LOAD_ERROR; + } + } + + if (HMainEditor.SelectEnd != 0 && Start > HMainEditor.SelectEnd) { + StatusBarSetStatusString (L"Invalid Block Start"); + return EFI_LOAD_ERROR; + } + + HMainEditor.SelectStart = Start; + + HBufferImageNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Load a disk buffer editor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandSelectEnd ( + VOID + ) +{ + UINTN End; + + End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column; + + // + // last line + // + if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { + if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) { + StatusBarSetStatusString (L"Invalid Block End"); + return EFI_LOAD_ERROR; + } + } + + if (HMainEditor.SelectStart != 0 && End < HMainEditor.SelectStart) { + StatusBarSetStatusString (L"Invalid Block End"); + return EFI_SUCCESS; + } + + HMainEditor.SelectEnd = End; + + HBufferImageNeedRefresh = TRUE; + + return EFI_SUCCESS; +} + +/** + Cut current line to clipboard. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandCut ( + VOID + ) +{ + UINTN Index; + LIST_ENTRY *Link; + UINT8 *Buffer; + UINTN Count; + + // + // not select, so not allowed to cut + // + if (HMainEditor.SelectStart == 0) { + StatusBarSetStatusString (L"No Block is Selected"); + return EFI_SUCCESS; + } + // + // not select, so not allowed to cut + // + if (HMainEditor.SelectEnd == 0) { + StatusBarSetStatusString (L"No Block is Selected"); + return EFI_SUCCESS; + } + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) { + Link = Link->ForwardLink; + } + + Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1; + Buffer = AllocateZeroPool (Count); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // cut the selected area + // + HBufferImageDeleteCharacterFromBuffer ( + HMainEditor.SelectStart - 1, + Count, + Buffer + ); + + // + // put to clipboard + // + HClipBoardSet (Buffer, Count); + + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + + if (!HMainEditor.BufferImage->Modified) { + HMainEditor.BufferImage->Modified = TRUE; + } + + // + // now no select area + // + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + + return EFI_SUCCESS; +} + +/** + Paste line to file buffer. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandPaste ( + VOID + ) +{ + + BOOLEAN OnlyLineRefresh; + HEFI_EDITOR_LINE *Line; + UINT8 *Buffer; + UINTN Count; + UINTN FPos; + + Count = HClipBoardGet (&Buffer); + if (Count == 0 || Buffer == NULL) { + StatusBarSetStatusString (L"Nothing to Paste"); + return EFI_SUCCESS; + } + + Line = HMainEditor.BufferImage->CurrentLine; + + OnlyLineRefresh = FALSE; + if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) { + // + // is at last line, and after paste will not exceed + // so only this line need to be refreshed + // + // if after add, the line is 0x10, then will append a new line + // so the whole page will need be refreshed + // + OnlyLineRefresh = TRUE; + + } + + FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1; + + HBufferImageAddCharacterToBuffer (FPos, Count, Buffer); + + if (OnlyLineRefresh) { + HBufferImageNeedRefresh = FALSE; + HBufferImageOnlyLineNeedRefresh = TRUE; + } else { + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + } + + if (!HMainEditor.BufferImage->Modified) { + HMainEditor.BufferImage->Modified = TRUE; + } + + return EFI_SUCCESS; + +} + +/** + Exit editor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandExit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Below is the scenario of Exit command: + // 1. IF currently opened file is not modified, exit the editor and + // Exit command ends. + // IF currently opened file is modified, do Step 2 + // + // 2. An Input Bar will be prompted: + // "File modified. Save ( Yes/No/Cancel )?" + // IF user press 'y' or 'Y', currently opened file will be saved and + // Editor exits + // IF user press 'n' or 'N', currently opened file will not be saved + // and Editor exits. + // IF user press 'c' or 'C' or ESC, Exit command ends. + // + // + // if file has been modified, so will prompt user + // whether to save the changes + // + if (HMainEditor.BufferImage->Modified) { + + Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // write file back to disk + // + Status = HBufferImageSave ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + HMainEditor.BufferImage->BufferType + ); + if (!EFI_ERROR (Status)) { + HEditorExit = TRUE; + } + + return Status; + + case L'n': + case L'N': + HEditorExit = TRUE; + return EFI_SUCCESS; + + case L'c': + case L'C': + return EFI_SUCCESS; + + } + } + } + + HEditorExit = TRUE; + return EFI_SUCCESS; + +} + +/** + Load a file from disk to editor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainCommandOpenFile ( + VOID + ) +{ + BOOLEAN Done; + EFI_STATUS Status; + EDIT_FILE_TYPE BufferType; + + BufferType = HMainEditor.BufferImage->BufferType; + + // + // This command will open a file from current working directory. + // Read-only file can also be opened. But it can not be modified. + // Below is the scenario of Open File command: + // 1. IF currently opened file has not been modified, directly go to step . + // IF currently opened file has been modified, an Input Bar will be + // prompted as : + // "File Modified. Save ( Yes/No/Cancel) ?" + // IF user press 'y' or 'Y', currently opened file will be saved. + // IF user press 'n' or 'N', currently opened file will + // not be saved. + // IF user press 'c' or 'C' or ESC, Open File command ends and + // currently opened file is still opened. + // + // 2. An Input Bar will be prompted as : "File Name to Open: " + // IF user press ESC, Open File command ends and + // currently opened file is still opened. + // Any other inputs with a Return will cause + // currently opened file close. + // + // 3. IF user input file name is an existing file , + // this file will be read and opened. + // IF user input file name is a new file, this file will be created + // and opened. This file's type ( UNICODE or ASCII ) is the same with + // the old file. + // + // + // if current file is modified, so you need to choose whether to + // save it first. + // + if (HMainEditor.BufferImage->Modified) { + + Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // the answer is just one character + // + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + // + // loop for user's answer + // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' + // + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // want to save this buffer first + // + Status = HBufferImageSave ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + HMainEditor.BufferImage->BufferType + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MainTitleBarRefresh ( + HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL, + HMainEditor.BufferImage->BufferType, + HMainEditor.BufferImage->FileImage->ReadOnly, + FALSE, + HMainEditor.ScreenSize.Column, + HMainEditor.ScreenSize.Row, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0 + ); + Done = TRUE; + break; + + case L'n': + case L'N': + // + // the file won't be saved + // + Done = TRUE; + break; + + case L'c': + case L'C': + return EFI_SUCCESS; + } + } + } + // + // TO get the open file name + // + Status = InputBarSetPrompt (L"File Name to Open: "); + if (EFI_ERROR (Status)) { + HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + return Status; + } + + Status = InputBarSetStringSize (100); + if (EFI_ERROR (Status)) { + Status = HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + Status = HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + + return Status; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + // + // CHECK if filename's valid + // + if (!IsValidFileName (InputBarGetString())) { + HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + + StatusBarSetStatusString (L"Invalid File Name"); + return EFI_SUCCESS; + } + + break; + } + } + // + // read from disk + // + Status = HBufferImageRead ( + InputBarGetString(), + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + FileTypeFileBuffer, + FALSE + ); + + if (EFI_ERROR (Status)) { + HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Load a disk buffer editor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_NOT_FOUND The disk was not found. +**/ +EFI_STATUS +HMainCommandOpenDisk ( + VOID + ) +{ + UINT64 Size; + UINT64 Offset; + CHAR16 *DeviceName; + EFI_STATUS Status; + BOOLEAN Done; + + EDIT_FILE_TYPE BufferType; + + // + // variable initialization + // + Size = 0; + Offset = 0; + BufferType = HMainEditor.BufferImage->BufferType; + + // + // if current file is modified, so you need to choose + // whether to save it first. + // + if (HMainEditor.BufferImage->Modified) { + + Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // the answer is just one character + // + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + // + // loop for user's answer + // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' + // + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // want to save this buffer first + // + Status = HBufferImageSave ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MainTitleBarRefresh ( + HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL, + HMainEditor.BufferImage->BufferType, + HMainEditor.BufferImage->FileImage->ReadOnly, + FALSE, + HMainEditor.ScreenSize.Column, + HMainEditor.ScreenSize.Row, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0 + ); + Done = TRUE; + break; + + case L'n': + case L'N': + // + // the file won't be saved + // + Done = TRUE; + break; + + case L'c': + case L'C': + return EFI_SUCCESS; + } + } + } + // + // get disk block device name + // + Status = InputBarSetPrompt (L"Block Device to Open: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (100); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + break; + } + } + + DeviceName = CatSPrint(NULL, L"%s", InputBarGetString()); + if (DeviceName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // get starting offset + // + Status = InputBarSetPrompt (L"First Block No.: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (16); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE); + if (EFI_ERROR (Status)) { + continue; + } + + break; + } + } + // + // get Number of Blocks: + // + Status = InputBarSetPrompt (L"Number of Blocks: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (8); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE); + if (EFI_ERROR (Status)) { + continue; + } + + if (Size == 0) { + continue; + } + + break; + } + } + + Status = HBufferImageRead ( + NULL, + DeviceName, + (UINTN)Offset, + (UINTN)Size, + 0, + 0, + FileTypeDiskBuffer, + FALSE + ); + + if (EFI_ERROR (Status)) { + + HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Load memory content to editor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_NOT_FOUND The disk was not found. +**/ +EFI_STATUS +HMainCommandOpenMemory ( + VOID + ) +{ + UINT64 Size; + UINT64 Offset; + EFI_STATUS Status; + BOOLEAN Done; + EDIT_FILE_TYPE BufferType; + + // + // variable initialization + // + Size = 0; + Offset = 0; + BufferType = HMainEditor.BufferImage->BufferType; + + // + // if current buffer is modified, so you need to choose + // whether to save it first. + // + if (HMainEditor.BufferImage->Modified) { + + Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); + if (EFI_ERROR (Status)) { + return Status; + } + // + // the answer is just one character + // + Status = InputBarSetStringSize (1); + if (EFI_ERROR (Status)) { + return Status; + } + // + // loop for user's answer + // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' + // + Done = FALSE; + while (!Done) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + return EFI_SUCCESS; + } + + switch (InputBarGetString()[0]) { + case L'y': + case L'Y': + // + // want to save this buffer first + // + Status = HBufferImageSave ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MainTitleBarRefresh ( + HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL, + HMainEditor.BufferImage->BufferType, + HMainEditor.BufferImage->FileImage->ReadOnly, + FALSE, + HMainEditor.ScreenSize.Column, + HMainEditor.ScreenSize.Row, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0 + ); + Done = TRUE; + break; + + case L'n': + case L'N': + // + // the file won't be saved + // + Done = TRUE; + break; + + case L'c': + case L'C': + return EFI_SUCCESS; + } + } + } + // + // get starting offset + // + Status = InputBarSetPrompt (L"Starting Offset: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (8); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE); + if (EFI_ERROR (Status)) { + continue; + } + + break; + } + } + // + // get Number of Blocks: + // + Status = InputBarSetPrompt (L"Buffer Size: "); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = InputBarSetStringSize (8); + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); + + // + // ESC pressed + // + if (Status == EFI_NOT_READY) { + + return EFI_SUCCESS; + } + // + // THE input string length should > 0 + // + if (StrLen (InputBarGetString()) > 0) { + Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE); + if (EFI_ERROR (Status)) { + continue; + } + + if (Size == 0) { + continue; + } + + break; + } + } + + if ((Offset + Size - 1)> 0xffffffff) { + StatusBarSetStatusString (L"Invalid parameter"); + return EFI_LOAD_ERROR; + } + + Status = HBufferImageRead ( + NULL, + NULL, + 0, + 0, + (UINTN)Offset, + (UINTN)Size, + FileTypeMemBuffer, + FALSE + ); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Device Error!"); + HBufferImageRead ( + HMainEditor.BufferImage->FileImage->FileName, + HMainEditor.BufferImage->DiskImage->Name, + HMainEditor.BufferImage->DiskImage->Offset, + HMainEditor.BufferImage->DiskImage->Size, + HMainEditor.BufferImage->MemImage->Offset, + HMainEditor.BufferImage->MemImage->Size, + BufferType, + TRUE + ); + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; + +} + +MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = { + NULL, + NULL, /* Ctrl - A */ + NULL, /* Ctrl - B */ + NULL, /* Ctrl - C */ + HMainCommandSelectEnd, /* Ctrl - D */ + HMainCommandDisplayHelp, /* Ctrl - E */ + NULL, /* Ctrl - F */ + HMainCommandGoToOffset, /* Ctrl - G */ + NULL, /* Ctrl - H */ + HMainCommandOpenDisk, /* Ctrl - I */ + NULL, /* Ctrl - J */ + NULL, /* Ctrl - K */ + NULL, /* Ctrl - L */ + HMainCommandOpenMemory, /* Ctrl - M */ + NULL, /* Ctrl - N */ + HMainCommandOpenFile, /* Ctrl - O */ + NULL, /* Ctrl - P */ + HMainCommandExit, /* Ctrl - Q */ + NULL, /* Ctrl - R */ + HMainCommandSaveBuffer, /* Ctrl - S */ + HMainCommandSelectStart, /* Ctrl - T */ + NULL, /* Ctrl - U */ + HMainCommandPaste, /* Ctrl - V */ + NULL, /* Ctrl - W */ + HMainCommandCut, /* Ctrl - X */ + NULL, /* Ctrl - Y */ + NULL, /* Ctrl - Z */ +}; + +CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = { + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1), + HMainCommandGoToOffset + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2), + HMainCommandSaveBuffer + }, + { + STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3), + HMainCommandExit + }, + + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4), + HMainCommandSelectStart + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5), + HMainCommandSelectEnd + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6), + HMainCommandCut + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7), + HMainCommandPaste + }, + + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8), + HMainCommandOpenFile + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9), + HMainCommandOpenDisk + }, + { + STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY), + STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10), + HMainCommandOpenMemory + }, + + { + 0, + 0, + NULL + } +}; + +/** + Init function for MainEditor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + + // + // basic initialization + // + CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor)); + + // + // set screen attributes + // + HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff; + + HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4); + + HOriginalColors = HMainEditor.ColorAttributes.Colors; + + HOriginalMode = gST->ConOut->Mode->Mode; + + // + // query screen size + // + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &(HMainEditor.ScreenSize.Column), + &(HMainEditor.ScreenSize.Row) + ); + + // + // Find TextInEx in System Table ConsoleInHandle + // Per UEFI Spec, TextInEx is required for a console capable platform. + // + Status = gBS->HandleProtocol ( + gST->ConsoleInHandle, + &gEfiSimpleTextInputExProtocolGuid, + (VOID**)&HMainEditor.TextInputEx + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Find mouse in System Table ConsoleInHandle + // + Status = gBS->HandleProtocol ( + gST->ConsoleInHandle, + &gEfiSimplePointerProtocolGuid, + (VOID**)&HMainEditor.MouseInterface + ); + if (EFI_ERROR (Status)) { + // + // If there is no Simple Pointer Protocol on System Table + // + HandleBuffer = NULL; + HMainEditor.MouseInterface = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimplePointerProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status) && HandleCount > 0) { + // + // Try to find the first available mouse device + // + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiSimplePointerProtocolGuid, + (VOID**)&HMainEditor.MouseInterface + ); + if (!EFI_ERROR (Status)) { + break; + } + } + } + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + } + + if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) { + HMainEditor.MouseAccumulatorX = 0; + HMainEditor.MouseAccumulatorY = 0; + HMainEditor.MouseSupported = TRUE; + } + + // + // below will call the five components' init function + // + Status = MainTitleBarInit (L"UEFI HEXEDIT"); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + Status = MenuBarInit (HexEditorMenuItems); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + Status = StatusBarInit (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + InputBarInit (HMainEditor.TextInputEx); + + Status = HBufferImageInit (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + + Status = HClipBoardInit (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle); + return EFI_LOAD_ERROR; + } + // + // clear whole screen and enable cursor + // + gST->ConOut->ClearScreen (gST->ConOut); + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + + // + // initialize EditorFirst and EditorExit + // + HEditorFirst = TRUE; + HEditorExit = FALSE; + HEditorMouseAction = FALSE; + + return EFI_SUCCESS; +} + +/** + Cleanup function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorCleanup ( + VOID + ) +{ + EFI_STATUS Status; + + // + // call the five components' cleanup function + // + MainTitleBarCleanup (); + + MenuBarCleanup (); + + StatusBarCleanup (); + + InputBarCleanup (); + + Status = HBufferImageCleanup (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle); + } + + Status = HClipBoardCleanup (); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle); + } + // + // restore old mode + // + if (HOriginalMode != gST->ConOut->Mode->Mode) { + gST->ConOut->SetMode (gST->ConOut, HOriginalMode); + } + + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background) + ); + gST->ConOut->ClearScreen (gST->ConOut); + + return EFI_SUCCESS; +} + +/** + Refresh function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMainEditorRefresh ( + VOID + ) +{ + BOOLEAN NameChange; + BOOLEAN ReadChange; + + NameChange = FALSE; + ReadChange = FALSE; + + if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) { + if (HMainEditor.BufferImage->DiskImage != NULL && + HBufferImageBackupVar.DiskImage != NULL && + (HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset || + HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size) ){ + NameChange = TRUE; + } + } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) { + if (HMainEditor.BufferImage->MemImage != NULL && + HBufferImageBackupVar.MemImage != NULL && + (HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset || + HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size) ){ + NameChange = TRUE; + } + } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) { + if ( HMainEditor.BufferImage->FileImage != NULL && + HMainEditor.BufferImage->FileImage->FileName != NULL && + HBufferImageBackupVar.FileImage != NULL && + HBufferImageBackupVar.FileImage->FileName != NULL && + StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0 ) { + NameChange = TRUE; + } + } + if ( HMainEditor.BufferImage->FileImage != NULL && + HBufferImageBackupVar.FileImage != NULL && + HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly ) { + ReadChange = TRUE; + } + + // + // to aVOID screen flicker + // the stall value is from experience + // + gBS->Stall (50); + + // + // call the components refresh function + // + if (HEditorFirst + || NameChange + || HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType + || HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified + || ReadChange ) { + + MainTitleBarRefresh ( + HMainEditor.BufferImage->BufferType == FileTypeFileBuffer&&HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Name:NULL, + HMainEditor.BufferImage->BufferType, + (BOOLEAN)(HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->ReadOnly:FALSE), + HMainEditor.BufferImage->Modified, + HMainEditor.ScreenSize.Column, + HMainEditor.ScreenSize.Row, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Offset:0, + HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Size :0 + ); + HBufferImageRefresh (); + } + if (HEditorFirst + || HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row + || HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column + || StatusBarGetRefresh()) { + + StatusBarRefresh ( + HEditorFirst, + HMainEditor.ScreenSize.Row, + HMainEditor.ScreenSize.Column, + (UINTN)(-1), + (UINTN)(-1), + FALSE + ); + HBufferImageRefresh (); + } + + if (HEditorFirst) { + HBufferImageRefresh (); + } + + // + // EditorFirst is now set to FALSE + // + HEditorFirst = FALSE; + + return EFI_SUCCESS; +} + +/** + Handle the mouse input. + + @param[in] MouseState The current mouse state. + @param[out] BeforeLeftButtonDown helps with selections. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_NOT_FOUND The disk was not found. +**/ +EFI_STATUS +HMainEditorHandleMouseInput ( + IN EFI_SIMPLE_POINTER_STATE MouseState, + OUT BOOLEAN *BeforeLeftButtonDown + ) +{ + + INT32 TextX; + INT32 TextY; + UINTN FRow; + UINTN FCol; + BOOLEAN HighBits; + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + UINTN Index; + BOOLEAN Action; + + Action = FALSE; + + // + // have mouse movement + // + if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) { + // + // handle + // + TextX = HGetTextX (MouseState.RelativeMovementX); + TextY = HGetTextY (MouseState.RelativeMovementY); + + HBufferImageAdjustMousePosition (TextX, TextY); + + Action = TRUE; + + } + + if (MouseState.LeftButton) { + HighBits = HBufferImageIsAtHighBits ( + HMainEditor.BufferImage->MousePosition.Column, + &FCol + ); + + // + // not at an movable place + // + if (FCol == 0) { + // + // now just move mouse pointer to legal position + // + // + // move mouse position to legal position + // + HMainEditor.BufferImage->MousePosition.Column -= 10; + if (HMainEditor.BufferImage->MousePosition.Column > 24) { + HMainEditor.BufferImage->MousePosition.Column--; + FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1; + } else { + if (HMainEditor.BufferImage->MousePosition.Column < 24) { + FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1; + } else { + // + // == 24 + // + FCol = 9; + } + } + + HighBits = TRUE; + + } + + FRow = HMainEditor.BufferImage->BufferPosition.Row + + HMainEditor.BufferImage->MousePosition.Row - + HMainEditor.BufferImage->DisplayPosition.Row; + + if (HMainEditor.BufferImage->NumLines < FRow) { + // + // dragging + // + // + // now just move mouse pointer to legal position + // + FRow = HMainEditor.BufferImage->NumLines; + HighBits = TRUE; + } + + Link = HMainEditor.BufferImage->ListHead->ForwardLink; + for (Index = 0; Index < FRow - 1; Index++) { + Link = Link->ForwardLink; + } + + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + + // + // dragging + // + // + // now just move mouse pointer to legal position + // + if (FCol > Line->Size) { + if (*BeforeLeftButtonDown) { + HighBits = FALSE; + + if (Line->Size == 0) { + if (FRow > 1) { + FRow--; + FCol = 16; + } else { + FRow = 1; + FCol = 1; + } + + } else { + FCol = Line->Size; + } + } else { + FCol = Line->Size + 1; + HighBits = TRUE; + } + } + + HBufferImageMovePosition (FRow, FCol, HighBits); + + HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row; + + HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column; + + *BeforeLeftButtonDown = TRUE; + + Action = TRUE; + } else { + // + // else of if LButton + // + // release LButton + // + if (*BeforeLeftButtonDown) { + Action = TRUE; + } + // + // mouse up + // + *BeforeLeftButtonDown = FALSE; + } + + if (Action) { + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + Handle user key input. will route it to other components handle function. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorKeyInput ( + VOID + ) +{ + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + EFI_SIMPLE_POINTER_STATE MouseState; + BOOLEAN NoShiftState; + BOOLEAN LengthChange; + UINTN Size; + UINTN OldSize; + BOOLEAN BeforeMouseIsDown; + BOOLEAN MouseIsDown; + BOOLEAN FirstDown; + BOOLEAN MouseDrag; + UINTN FRow; + UINTN FCol; + UINTN SelectStartBackup; + UINTN SelectEndBackup; + + // + // variable initialization + // + OldSize = 0; + FRow = 0; + FCol = 0; + LengthChange = FALSE; + + MouseIsDown = FALSE; + FirstDown = FALSE; + MouseDrag = FALSE; + + do { + + Status = EFI_SUCCESS; + + HEditorMouseAction = FALSE; + + // + // backup some key elements, so that can aVOID some refresh work + // + HMainEditorBackup (); + + // + // wait for user key input + // + // + // change priority of checking mouse/keyboard activity dynamically + // so prevent starvation of keyboard. + // if last time, mouse moves then this time check keyboard + // + if (HMainEditor.MouseSupported) { + Status = HMainEditor.MouseInterface->GetState ( + HMainEditor.MouseInterface, + &MouseState + ); + if (!EFI_ERROR (Status)) { + + BeforeMouseIsDown = MouseIsDown; + + Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown); + + if (!EFI_ERROR (Status)) { + if (!BeforeMouseIsDown) { + // + // mouse down + // + if (MouseIsDown) { + FRow = HBufferImage.BufferPosition.Row; + FCol = HBufferImage.BufferPosition.Column; + SelectStartBackup = HMainEditor.SelectStart; + SelectEndBackup = HMainEditor.SelectEnd; + + FirstDown = TRUE; + } + } else { + + SelectStartBackup = HMainEditor.SelectStart; + SelectEndBackup = HMainEditor.SelectEnd; + + // + // begin to drag + // + if (MouseIsDown) { + if (FirstDown) { + if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) { + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol; + + MouseDrag = TRUE; + FirstDown = FALSE; + } + } else { + if (( + (HBufferImage.BufferPosition.Row - 1) * + 0x10 + + HBufferImage.BufferPosition.Column + ) >= HMainEditor.SelectStart + ) { + HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) * + 0x10 + + HBufferImage.BufferPosition.Column; + } else { + HMainEditor.SelectEnd = 0; + } + } + // + // end of if RelativeX/Y + // + } else { + // + // mouse is up + // + if (MouseDrag) { + if (HBufferImageGetTotalSize () == 0) { + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + FirstDown = FALSE; + MouseDrag = FALSE; + } + + if (( + (HBufferImage.BufferPosition.Row - 1) * + 0x10 + + HBufferImage.BufferPosition.Column + ) >= HMainEditor.SelectStart + ) { + HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) * + 0x10 + + HBufferImage.BufferPosition.Column; + } else { + HMainEditor.SelectEnd = 0; + } + + if (HMainEditor.SelectEnd == 0) { + HMainEditor.SelectStart = 0; + } + } + + FirstDown = FALSE; + MouseDrag = FALSE; + } + + if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) { + if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) { + HBufferImageNeedRefresh = TRUE; + } else { + if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) { + HBufferImageNeedRefresh = TRUE; + } else { + HBufferImageOnlyLineNeedRefresh = TRUE; + } + } + } + } + + HEditorMouseAction = TRUE; + HBufferImageMouseNeedRefresh = TRUE; + + } else if (Status == EFI_LOAD_ERROR) { + StatusBarSetStatusString (L"Invalid Mouse Movement "); + } + } + } + + // + // CheckEvent() returns Success when non-partial key is pressed. + // + Status = gBS->CheckEvent (HMainEditor.TextInputEx->WaitForKeyEx); + if (!EFI_ERROR (Status)) { + Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData); + if (!EFI_ERROR (Status)) { + // + // dispatch to different components' key handling function + // so not everywhere has to set this variable + // + HBufferImageMouseNeedRefresh = TRUE; + + // + // clear previous status string + // + StatusBarSetRefresh(); + // + // NoShiftState: TRUE when no shift key is pressed. + // + NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID); + // + // dispatch to different components' key handling function + // + if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&KeyData)) { + Status = EFI_SUCCESS; + } else if (NoShiftState && KeyData.Key.ScanCode == SCAN_NULL) { + Status = HBufferImageHandleInput (&KeyData.Key); + } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) { + Status = HBufferImageHandleInput (&KeyData.Key); + } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && KeyData.Key.ScanCode <= SCAN_F12)) { + Status = MenuBarDispatchFunctionKey (&KeyData.Key); + } else { + StatusBarSetStatusString (L"Unknown Command"); + + HBufferImageMouseNeedRefresh = FALSE; + } + + if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) { + // + // not already has some error status + // + if (StrCmp (L"", StatusBarGetString()) == 0) { + StatusBarSetStatusString (L"Disk Error. Try Again"); + } + } + } + // + // decide if has to set length warning + // + if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) { + LengthChange = FALSE; + } else { + // + // still the old buffer + // + if (HBufferImage.BufferType != FileTypeFileBuffer) { + Size = HBufferImageGetTotalSize (); + + switch (HBufferImage.BufferType) { + case FileTypeDiskBuffer: + OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize; + break; + + case FileTypeMemBuffer: + OldSize = HBufferImage.MemImage->Size; + break; + + default: + OldSize = 0; + break; + } + + if (!LengthChange) { + if (OldSize != Size) { + StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed"); + } + } + + if (OldSize != Size) { + LengthChange = TRUE; + } else { + LengthChange = FALSE; + } + } + } + } + // + // after handling, refresh editor + // + HMainEditorRefresh (); + + } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit); + + return Status; +} + +/** + Backup function for MainEditor. +**/ +VOID +HMainEditorBackup ( + VOID + ) +{ + HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart; + HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd; + HBufferImageBackup (); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h new file mode 100644 index 00000000..8cce1991 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.h @@ -0,0 +1,69 @@ +/** @file + Defines the Main Editor data type - + - Global variables + - Instances of the other objects of the editor + - Main Interfaces + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_EDITOR_H_ +#define _LIB_EDITOR_H_ + +#include "HexEditor.h" + +/** + Init function for MainEditor + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorInit ( + VOID + ); + +/** + Cleanup function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorCleanup ( + VOID + ); + +/** + Refresh function for MainEditor. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMainEditorRefresh ( + VOID + ); + +/** + Handle user key input. will route it to other components handle function. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation occurred. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMainEditorKeyInput ( + VOID + ); + +/** + Backup function for MainEditor. +**/ +VOID +HMainEditorBackup ( + VOID + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c new file mode 100644 index 00000000..ffafb90c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.c @@ -0,0 +1,278 @@ +/** @file + Functions to deal with Mem buffer + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern EFI_HANDLE HImageHandleBackup; + +extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; + +extern BOOLEAN HBufferImageNeedRefresh; +extern BOOLEAN HBufferImageOnlyLineNeedRefresh; +extern BOOLEAN HBufferImageMouseNeedRefresh; + +extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; + +HEFI_EDITOR_MEM_IMAGE HMemImage; +HEFI_EDITOR_MEM_IMAGE HMemImageBackupVar; + +// +// for basic initialization of HDiskImage +// +HEFI_EDITOR_MEM_IMAGE HMemImageConst = { + NULL, + 0, + 0 +}; + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMemImageInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // basically initialize the HMemImage + // + CopyMem (&HMemImage, &HMemImageConst, sizeof (HMemImage)); + + Status = gBS->LocateProtocol ( + &gEfiCpuIo2ProtocolGuid, + NULL, + (VOID**)&HMemImage.IoFncs + ); + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } else { + return EFI_LOAD_ERROR; + } +} + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMemImageBackup ( + VOID + ) +{ + HMemImageBackupVar.Offset = HMemImage.Offset; + HMemImageBackupVar.Size = HMemImage.Size; + + return EFI_SUCCESS; +} + +/** + Set FileName field in HFileImage. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSetMemOffsetSize ( + IN UINTN Offset, + IN UINTN Size + ) +{ + + HMemImage.Offset = Offset; + HMemImage.Size = Size; + + return EFI_SUCCESS; +} + +/** + Read a disk from disk into HBufferImage. + + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageRead ( + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ) +{ + + EFI_STATUS Status; + void *Buffer; + CHAR16 *Str; + HEFI_EDITOR_LINE *Line; + + HBufferImage.BufferType = FileTypeMemBuffer; + + Buffer = AllocateZeroPool (Size); + if (Buffer == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + Status = HMemImage.IoFncs->Mem.Read ( + HMemImage.IoFncs, + EfiCpuIoWidthUint8, + Offset, + Size, + Buffer + ); + + if (EFI_ERROR (Status)) { + FreePool (Buffer); + StatusBarSetStatusString (L"Memory Specified Not Accessible"); + return EFI_LOAD_ERROR; + } + + HBufferImageFree (); + + Status = HBufferImageBufferToList (Buffer, Size); + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + StatusBarSetStatusString (L"Read Memory Failed"); + return Status; + } + + Status = HMemImageSetMemOffsetSize (Offset, Size); + + HBufferImage.DisplayPosition.Row = 2; + HBufferImage.DisplayPosition.Column = 10; + + HBufferImage.MousePosition.Row = 2; + HBufferImage.MousePosition.Column = 10; + + HBufferImage.LowVisibleRow = 1; + HBufferImage.HighBits = TRUE; + + HBufferImage.BufferPosition.Row = 1; + HBufferImage.BufferPosition.Column = 1; + + if (!Recover) { + Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); + if (Str == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + StatusBarSetStatusString (Str); + SHELL_FREE_NON_NULL (Str); + + HMainEditor.SelectStart = 0; + HMainEditor.SelectEnd = 0; + + } + + // + // has line + // + if (HBufferImage.Lines != NULL) { + HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } else { + // + // create a dummy line + // + Line = HBufferImageCreateLine (); + if (Line == NULL) { + StatusBarSetStatusString (L"Read Memory Failed"); + return EFI_OUT_OF_RESOURCES; + } + + HBufferImage.CurrentLine = Line; + } + + HBufferImage.Modified = FALSE; + HBufferImageNeedRefresh = TRUE; + HBufferImageOnlyLineNeedRefresh = FALSE; + HBufferImageMouseNeedRefresh = TRUE; + + return EFI_SUCCESS; + +} + +/** + Save lines in HBufferImage to disk. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSave ( + IN UINTN Offset, + IN UINTN Size + ) +{ + + EFI_STATUS Status; + VOID *Buffer; + + // + // not modified, so directly return + // + if (HBufferImage.Modified == FALSE) { + return EFI_SUCCESS; + } + + HBufferImage.BufferType = FileTypeMemBuffer; + + Buffer = AllocateZeroPool (Size); + + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = HBufferImageListToBuffer (Buffer, Size); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + // + // write back to memory + // + Status = HMemImage.IoFncs->Mem.Write ( + HMemImage.IoFncs, + EfiCpuIoWidthUint8, + Offset, + Size, + Buffer + ); + + FreePool (Buffer); + + if (EFI_ERROR (Status)) { + return EFI_LOAD_ERROR; + } + // + // now not modified + // + HBufferImage.Modified = FALSE; + + return EFI_SUCCESS; +} + + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h new file mode 100644 index 00000000..5a398a94 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MemImage.h @@ -0,0 +1,86 @@ +/** @file + Defines MemImage - the view of the file that is visible at any point, + as well as the event handlers for editing the file + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MEM_IMAGE_H_ +#define _LIB_MEM_IMAGE_H_ + +#include "HexEditor.h" + +/** + Initialization function for HDiskImage. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_LOAD_ERROR A load error occurred. +**/ +EFI_STATUS +HMemImageInit ( + VOID + ); + +/** + Backup function for HDiskImage. Only a few fields need to be backup. + This is for making the Disk buffer refresh as few as possible. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HMemImageBackup ( + VOID + ); + +/** + Set FileName field in HFileImage. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSetMemOffsetSize ( + IN UINTN Offset, + IN UINTN Size + ); + +/** + Read a disk from disk into HBufferImage. + + @param[in] Offset The offset. + @param[in] Size The size. + @param[in] Recover if is for recover, no information print. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageRead ( + IN UINTN Offset, + IN UINTN Size, + IN BOOLEAN Recover + ); + +/** + Save lines in HBufferImage to disk. + + @param[in] Offset The offset. + @param[in] Size The size. + + @retval EFI_LOAD_ERROR A load error occurred. + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +HMemImageSave ( + IN UINTN Offset, + IN UINTN Size + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c new file mode 100644 index 00000000..31ce112a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c @@ -0,0 +1,256 @@ +/** @file + Implementation of various string and line routines + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HexEditor.h" + +extern BOOLEAN HEditorMouseAction; + +/** + Free a line and it's internal buffer. + + @param[in] Src The line to be freed. +**/ +VOID +HLineFree ( + IN HEFI_EDITOR_LINE *Src + ) +{ + if (Src == NULL) { + return ; + } + + SHELL_FREE_NON_NULL (Src); + +} + +/** + Advance to the next Count lines. + + @param[in] Count The line number to advance. + + @retval NULL An error occurred. + @return A pointer to the line after advance. +**/ +HEFI_EDITOR_LINE * +HLineAdvance ( + IN UINTN Count + ) +{ + UINTN Index; + HEFI_EDITOR_LINE *Line; + + Line = HMainEditor.BufferImage->CurrentLine; + if (Line == NULL) { + return NULL; + } + + for (Index = 0; Index < Count; Index++) { + // + // if already last line + // + if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { + return NULL; + } + + Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } + + return Line; +} + +/** + Retreat to the previous Count lines. + + @param[in] Count The line number to retreat. + + @retval NULL An error occurred. + @return A pointer to the line after retreat. +**/ +HEFI_EDITOR_LINE * +HLineRetreat ( + IN UINTN Count + ) +{ + UINTN Index; + HEFI_EDITOR_LINE *Line; + + Line = HMainEditor.BufferImage->CurrentLine; + if (Line == NULL) { + return NULL; + } + + for (Index = 0; Index < Count; Index++) { + // + // already the first line + // + if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) { + return NULL; + } + + Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + } + + return Line; +} + +/** + Advance/Retreat lines. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveLine ( + IN INTN Count + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN AbsCount; + + // + // difference with MoveCurrentLine + // just return Line + // do not set currentline to Line + // + if (Count <= 0) { + AbsCount = (UINTN)ABS(Count); + Line = HLineRetreat (AbsCount); + } else { + Line = HLineAdvance ((UINTN)Count); + } + + return Line; +} + +/** + Advance/Retreat lines and set CurrentLine in BufferImage to it. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveCurrentLine ( + IN INTN Count + ) +{ + HEFI_EDITOR_LINE *Line; + UINTN AbsCount; + + // + // <0: retreat + // >0: advance + // + if (Count <= 0) { + AbsCount = (UINTN)ABS(Count); + Line = HLineRetreat (AbsCount); + } else { + Line = HLineAdvance ((UINTN)Count); + } + + if (Line == NULL) { + return NULL; + } + + HMainEditor.BufferImage->CurrentLine = Line; + + return Line; +} + + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @param[in] ListHead The list head. + @param[in] Lines The lines. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFreeLines ( + IN LIST_ENTRY *ListHead, + IN HEFI_EDITOR_LINE *Lines + ) +{ + LIST_ENTRY *Link; + HEFI_EDITOR_LINE *Line; + + // + // release all the lines + // + if (Lines != NULL) { + + Line = Lines; + Link = &(Line->Link); + do { + Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); + Link = Link->ForwardLink; + HLineFree (Line); + } while (Link != ListHead); + } + + ListHead->ForwardLink = ListHead; + ListHead->BackLink = ListHead; + + return EFI_SUCCESS; +} + +/** + Get the X information for the mouse. + + @param[in] GuidX The change. + + @return the new information. +**/ +INT32 +HGetTextX ( + IN INT32 GuidX + ) +{ + INT32 Gap; + + HMainEditor.MouseAccumulatorX += GuidX; + Gap = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX); + HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX); + HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32) HMainEditor.ScreenSize.Column; + return Gap; +} + +/** + Get the Y information for the mouse. + + @param[in] GuidY The change. + + @return the new information. +**/ +INT32 +HGetTextY ( + IN INT32 GuidY + ) +{ + INT32 Gap; + + HMainEditor.MouseAccumulatorY += GuidY; + Gap = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY); + HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY); + HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32) HMainEditor.ScreenSize.Row; + + return Gap; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h new file mode 100644 index 00000000..4f941a60 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.h @@ -0,0 +1,87 @@ +/** @file + Definitions for various line and string routines + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_MISC_H_ +#define _LIB_MISC_H_ + +#include "HexEditor.h" + +/** + Advance/Retreat lines. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveLine ( + IN INTN Count + ); + +/** + Advance/Retreat lines and set CurrentLine in BufferImage to it. + + @param[in] Count The line number to advance/retreat. + >0 : advance + <0: retreat + + @retval NULL An error occurred. + @return A pointer to the line after move. +**/ +HEFI_EDITOR_LINE * +HMoveCurrentLine ( + IN INTN Count + ); + +/** + Free all the lines in HBufferImage. + Fields affected: + Lines + CurrentLine + NumLines + ListHead + + @param[in] ListHead The list head. + @param[in] Lines The lines. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +HFreeLines ( + IN LIST_ENTRY *ListHead, + IN HEFI_EDITOR_LINE *Lines + ); + +/** + Get the X information for the mouse. + + @param[in] GuidX The change. + + @return the new information. +**/ +INT32 +HGetTextX ( + IN INT32 GuidX + ); + +/** + Get the Y information for the mouse. + + @param[in] GuidY The change. + + @return the new information. +**/ +INT32 +HGetTextY ( + IN INT32 GuidY + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c new file mode 100644 index 00000000..5ac430a2 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c @@ -0,0 +1,412 @@ +/** @file + Main file for LoadPciRom shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <IndustryStandard/Pci22.h> +#include <IndustryStandard/Pci23.h> +#include <IndustryStandard/PeImage.h> +#include <Protocol/Decompress.h> + +/** + Connects all available drives and controllers. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The abort mechanism was received. +**/ +EFI_STATUS +LoadPciRomConnectAllDriversToAllControllers ( + VOID + ); + +/** + Command entry point. + + @param[in] RomBar The Rom Base address. + @param[in] RomSize The Rom size. + @param[in] FileName The file name. + + @retval EFI_SUCCESS The command completed successfully. + @retval EFI_INVALID_PARAMETER Command usage error. + @retval EFI_UNSUPPORTED Protocols unsupported. + @retval EFI_OUT_OF_RESOURCES Out of memory. + @retval Other value Unknown error. +**/ +EFI_STATUS +LoadEfiDriversFromRomImage ( + VOID *RomBar, + UINTN RomSize, + CONST CHAR16 *FileName + ); + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-nc", TypeFlag}, + {NULL, TypeMax} + }; + +/** + Function for 'loadpcirom' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLoadPciRom ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_SHELL_FILE_INFO *FileList; + UINTN SourceSize; + UINT8 *File1Buffer; + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + BOOLEAN Connect; + CONST CHAR16 *Param; + UINTN ParamCount; + EFI_SHELL_FILE_INFO *Node; + // + // Local variable initializations + // + File1Buffer = NULL; + ShellStatus = SHELL_SUCCESS; + FileList = NULL; + + + // + // verify number of arguments + // + 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), gShellDebug1HiiHandle, L"loadpcirom", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) < 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"loadpcirom"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (ShellCommandLineGetFlag(Package, L"-nc")) { + Connect = FALSE; + } else { + Connect = TRUE; + } + + // + // get a list with each file specified by parameters + // if parameter is a directory then add all the files below it to the list + // + for ( ParamCount = 1, Param = ShellCommandLineGetRawValue(Package, ParamCount) + ; Param != NULL + ; ParamCount++, Param = ShellCommandLineGetRawValue(Package, ParamCount) + ){ + Status = ShellOpenFileMetaArg((CHAR16*)Param, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Param); + ShellStatus = SHELL_ACCESS_DENIED; + break; + } + } + if (ShellStatus == SHELL_SUCCESS && FileList != NULL) { + // + // loop through the list and make sure we are not aborting... + // + for ( Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link) + ; !IsNull(&FileList->Link, &Node->Link) && !ShellGetExecutionBreakFlag() + ; Node = (EFI_SHELL_FILE_INFO*)GetNextNode(&FileList->Link, &Node->Link) + ){ + if (EFI_ERROR(Node->Status)){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName); + ShellStatus = SHELL_INVALID_PARAMETER; + continue; + } + if (FileHandleIsDirectory(Node->Handle) == EFI_SUCCESS) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName); + ShellStatus = SHELL_INVALID_PARAMETER; + continue; + } + SourceSize = (UINTN) Node->Info->FileSize; + File1Buffer = AllocateZeroPool (SourceSize); + if (File1Buffer == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"loadpcirom"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + continue; + } + Status = gEfiShellProtocol->ReadFile(Node->Handle, &SourceSize, File1Buffer); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_READ_FAIL), gShellDebug1HiiHandle, L"loadpcirom", Node->FullName); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = LoadEfiDriversFromRomImage ( + File1Buffer, + SourceSize, + Node->FullName + ); + + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_PCI_ROM_RES), gShellDebug1HiiHandle, Node->FullName, Status); + } + FreePool(File1Buffer); + } + } else if (ShellStatus == SHELL_SUCCESS) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_SPEC), gShellDebug1HiiHandle, "loadpcirom"); + ShellStatus = SHELL_NOT_FOUND; + } + if (FileList != NULL && !IsListEmpty(&FileList->Link)) { + Status = ShellCloseFileMetaArg(&FileList); + } + FileList = NULL; + + if (Connect) { + Status = LoadPciRomConnectAllDriversToAllControllers (); + } + } + } + + return (ShellStatus); +} + +/** + Command entry point. + + @param[in] RomBar The Rom Base address. + @param[in] RomSize The Rom size. + @param[in] FileName The file name. + + @retval EFI_SUCCESS The command completed successfully. + @retval EFI_INVALID_PARAMETER Command usage error. + @retval EFI_UNSUPPORTED Protocols unsupported. + @retval EFI_OUT_OF_RESOURCES Out of memory. + @retval Other value Unknown error. +**/ +EFI_STATUS +LoadEfiDriversFromRomImage ( + VOID *RomBar, + UINTN RomSize, + CONST CHAR16 *FileName + ) + +{ + EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; + PCI_DATA_STRUCTURE *Pcir; + UINTN ImageIndex; + UINTN RomBarOffset; + UINT32 ImageSize; + UINT16 ImageOffset; + EFI_HANDLE ImageHandle; + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + CHAR16 RomFileName[280]; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + BOOLEAN SkipImage; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINT8 *Scratch; + VOID *ImageBuffer; + VOID *DecompressedImageBuffer; + UINT32 ImageLength; + EFI_DECOMPRESS_PROTOCOL *Decompress; + UINT32 InitializationSize; + + ImageIndex = 0; + ReturnStatus = EFI_NOT_FOUND; + RomBarOffset = (UINTN) RomBar; + + do { + + EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset; + + if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_CORRUPT), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex); +// PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex); + return ReturnStatus; + } + + // + // If the pointer to the PCI Data Structure is invalid, no further images can be located. + // The PCI Data Structure must be DWORD aligned. + // + if (EfiRomHeader->PcirOffset == 0 || + (EfiRomHeader->PcirOffset & 3) != 0 || + RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) { + break; + } + + Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset); + // + // If a valid signature is not present in the PCI Data Structure, no further images can be located. + // + if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { + break; + } + ImageSize = Pcir->ImageLength * 512; + if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) { + break; + } + + if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && + (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) && + ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || + (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) { + + ImageOffset = EfiRomHeader->EfiImageHeaderOffset; + InitializationSize = EfiRomHeader->InitializationSize * 512; + + if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) { + + ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset); + ImageLength = InitializationSize - ImageOffset; + DecompressedImageBuffer = NULL; + + // + // decompress here if needed + // + SkipImage = FALSE; + if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + SkipImage = TRUE; + } + + if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID**)&Decompress); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR (Status)) { + SkipImage = TRUE; + } else { + SkipImage = TRUE; + Status = Decompress->GetInfo ( + Decompress, + ImageBuffer, + ImageLength, + &DestinationSize, + &ScratchSize + ); + if (!EFI_ERROR (Status)) { + DecompressedImageBuffer = AllocateZeroPool (DestinationSize); + if (ImageBuffer != NULL) { + Scratch = AllocateZeroPool (ScratchSize); + if (Scratch != NULL) { + Status = Decompress->Decompress ( + Decompress, + ImageBuffer, + ImageLength, + DecompressedImageBuffer, + DestinationSize, + Scratch, + ScratchSize + ); + if (!EFI_ERROR (Status)) { + ImageBuffer = DecompressedImageBuffer; + ImageLength = DestinationSize; + SkipImage = FALSE; + } + + FreePool (Scratch); + } + } + } + } + } + + if (!SkipImage) { + // + // load image and start image + // + UnicodeSPrint (RomFileName, sizeof (RomFileName), L"%s[%d]", FileName, ImageIndex); + FilePath = FileDevicePath (NULL, RomFileName); + + Status = gBS->LoadImage ( + TRUE, + gImageHandle, + FilePath, + ImageBuffer, + ImageLength, + &ImageHandle + ); + if (EFI_ERROR (Status)) { + // + // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created + // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now. + // If the caller doesn't have the option to defer the execution of an image, we should + // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak. + // + if (Status == EFI_SECURITY_VIOLATION) { + gBS->UnloadImage (ImageHandle); + } + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_LOAD_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex); +// PrintToken (STRING_TOKEN (STR_LOADPCIROM_LOAD_IMAGE_ERROR), HiiHandle, ImageIndex, Status); + } else { + Status = gBS->StartImage (ImageHandle, NULL, NULL); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_START_FAIL), gShellDebug1HiiHandle, L"loadpcirom", FileName, ImageIndex); +// PrintToken (STRING_TOKEN (STR_LOADPCIROM_START_IMAGE), HiiHandle, ImageIndex, Status); + } else { + ReturnStatus = Status; + } + } + } + + if (DecompressedImageBuffer != NULL) { + FreePool (DecompressedImageBuffer); + } + + } + } + + RomBarOffset = RomBarOffset + ImageSize; + ImageIndex++; + } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize)); + + return ReturnStatus; +} + +/** + Connects all available drives and controllers. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_ABORTED The abort mechanism was received. +**/ +EFI_STATUS +LoadPciRomConnectAllDriversToAllControllers ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + if (ShellGetExecutionBreakFlag ()) { + Status = EFI_ABORTED; + break; + } + gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + return Status; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/MemMap.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/MemMap.c new file mode 100644 index 00000000..972b2abd --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/MemMap.c @@ -0,0 +1,404 @@ +/** @file + Main file for Mode shell Debug1 function. + + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// Need full names for Standard-Format Output +// +STATIC CONST CHAR16 NameEfiReservedMemoryType[] = L"Reserved"; +STATIC CONST CHAR16 NameEfiLoaderCode[] = L"LoaderCode"; +STATIC CONST CHAR16 NameEfiLoaderData[] = L"LoaderData"; +STATIC CONST CHAR16 NameEfiBootServicesCode[] = L"BootServiceCode"; +STATIC CONST CHAR16 NameEfiBootServicesData[] = L"BootServiceData"; +STATIC CONST CHAR16 NameEfiRuntimeServicesCode[] = L"RuntimeCode"; +STATIC CONST CHAR16 NameEfiRuntimeServicesData[] = L"RuntimeData"; +STATIC CONST CHAR16 NameEfiConventionalMemory[] = L"Available"; +STATIC CONST CHAR16 NameEfiPersistentMemory[] = L"Persistent"; +STATIC CONST CHAR16 NameEfiUnusableMemory[] = L"UnusableMemory"; +STATIC CONST CHAR16 NameEfiACPIReclaimMemory[] = L"ACPIReclaimMemory"; +STATIC CONST CHAR16 NameEfiACPIMemoryNVS[] = L"ACPIMemoryNVS"; +STATIC CONST CHAR16 NameEfiMemoryMappedIO[] = L"MemoryMappedIO"; +STATIC CONST CHAR16 NameEfiMemoryMappedIOPortSpace[] = L"MemoryMappedIOPortSpace"; +STATIC CONST CHAR16 NameEfiPalCode[] = L"PalCode"; + +// +// Need short names for some memory types +// +STATIC CONST CHAR16 NameEfiBootServicesCodeShort[] = L"BS_Code"; +STATIC CONST CHAR16 NameEfiBootServicesDataShort[] = L"BS_Data"; +STATIC CONST CHAR16 NameEfiRuntimeServicesCodeShort[] = L"RT_Code"; +STATIC CONST CHAR16 NameEfiRuntimeServicesDataShort[] = L"RT_Data"; +STATIC CONST CHAR16 NameEfiUnusableMemoryShort[] = L"Unusable"; +STATIC CONST CHAR16 NameEfiACPIReclaimMemoryShort[] = L"ACPI_Recl"; +STATIC CONST CHAR16 NameEfiACPIMemoryNVSShort[] = L"ACPI_NVS"; +STATIC CONST CHAR16 NameEfiMemoryMappedIOShort[] = L"MMIO"; +STATIC CONST CHAR16 NameEfiMemoryMappedIOPortSpaceShort[] = L"MMIO_Port"; + +#include "UefiShellDebug1CommandsLib.h" + +typedef struct { + UINT32 Type; + UINT64 NumberOfPages; + LIST_ENTRY Link; +} MEMORY_LENGTH_ENTRY; + +/** + Add the length of the specified type to List. + + @param List A list to hold all pairs of <Type, NumberOfPages>. + @param Type Memory type. + @param NumberOfPages Number of pages. +**/ +VOID +AddMemoryLength ( + LIST_ENTRY *List, + UINT32 Type, + UINT64 NumberOfPages + ) +{ + MEMORY_LENGTH_ENTRY *Entry; + MEMORY_LENGTH_ENTRY *NewEntry; + LIST_ENTRY *Link; + + Entry = NULL; + for (Link = GetFirstNode (List); !IsNull (List, Link); Link = GetNextNode (List, Link)) { + Entry = BASE_CR (Link, MEMORY_LENGTH_ENTRY, Link); + if (Entry->Type >= Type) { + break; + } + } + + if ((Entry != NULL) && (Entry->Type == Type)) { + // + // The Entry is the one we look for. + // + NewEntry = Entry; + } else { + // + // The search operation breaks due to: + // 1. Type of every entry < Type --> Insert to tail + // 2. Type of an entry > Type --> Insert to previous of this entry + // + NewEntry = AllocatePool (sizeof (*NewEntry)); + if (NewEntry == NULL) { + return; + } + NewEntry->Type = Type; + NewEntry->NumberOfPages = 0; + InsertTailList (Link, &NewEntry->Link); + } + + NewEntry->NumberOfPages += NumberOfPages; +} + +/** + Function for 'memmap' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMemMap ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINTN Size; + EFI_MEMORY_DESCRIPTOR *Descriptors; + UINTN MapKey; + UINTN ItemSize; + UINT32 Version; + EFI_MEMORY_DESCRIPTOR *Walker; + UINT64 ReservedPages; + UINT64 LoadCodePages; + UINT64 LoadDataPages; + UINT64 BSCodePages; + UINT64 BSDataPages; + UINT64 RTDataPages; + UINT64 RTCodePages; + UINT64 AvailPages; + UINT64 TotalPages; + UINT64 ReservedPagesSize; + UINT64 LoadCodePagesSize; + UINT64 LoadDataPagesSize; + UINT64 BSCodePagesSize; + UINT64 BSDataPagesSize; + UINT64 RTDataPagesSize; + UINT64 RTCodePagesSize; + UINT64 AvailPagesSize; + UINT64 TotalPagesSize; + UINT64 AcpiReclaimPages; + UINT64 AcpiNvsPages; + UINT64 MmioSpacePages; + UINT64 AcpiReclaimPagesSize; + UINT64 AcpiNvsPagesSize; + UINT64 MmioSpacePagesSize; + UINT64 MmioPortPages; + UINT64 MmioPortPagesSize; + UINT64 UnusableMemoryPages; + UINT64 UnusableMemoryPagesSize; + UINT64 PalCodePages; + UINT64 PalCodePagesSize; + UINT64 PersistentPages; + UINT64 PersistentPagesSize; + BOOLEAN Sfo; + LIST_ENTRY MemoryList; + MEMORY_LENGTH_ENTRY *Entry; + LIST_ENTRY *Link; + + AcpiReclaimPages = 0; + AcpiNvsPages = 0; + MmioSpacePages = 0; + TotalPages = 0; + ReservedPages = 0; + LoadCodePages = 0; + LoadDataPages = 0; + BSCodePages = 0; + BSDataPages = 0; + RTDataPages = 0; + RTCodePages = 0; + AvailPages = 0; + MmioPortPages = 0; + UnusableMemoryPages = 0; + PalCodePages = 0; + PersistentPages = 0; + Size = 0; + Descriptors = NULL; + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + InitializeListHead (&MemoryList); + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"memmap", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 1) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"memmap"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Status = gBS->GetMemoryMap(&Size, Descriptors, &MapKey, &ItemSize, &Version); + if (Status == EFI_BUFFER_TOO_SMALL){ + Size += SIZE_1KB; + Descriptors = AllocateZeroPool(Size); + Status = gBS->GetMemoryMap(&Size, Descriptors, &MapKey, &ItemSize, &Version); + } + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_GET_FAILED), gShellDebug1HiiHandle, L"memmap"); + ShellStatus = SHELL_ACCESS_DENIED; + } else { + ASSERT(Version == EFI_MEMORY_DESCRIPTOR_VERSION); + + Sfo = ShellCommandLineGetFlag(Package, L"-sfo"); + if (!Sfo) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_HEAD), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"memmap"); + } + + for ( Walker = Descriptors + ; (Walker < (EFI_MEMORY_DESCRIPTOR *) ((UINT8*)Descriptors + Size)) && (Walker != NULL) + ; Walker = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *)Walker + ItemSize) + ){ + switch (Walker->Type) { + case EfiReservedMemoryType: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiReservedMemoryType, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + ReservedPages += Walker->NumberOfPages; + break; + case EfiLoaderCode: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + LoadCodePages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiLoaderData: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiLoaderData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + LoadDataPages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiBootServicesCode: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesCodeShort:NameEfiBootServicesCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + BSCodePages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiBootServicesData: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiBootServicesDataShort:NameEfiBootServicesData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + BSDataPages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiRuntimeServicesCode: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesCodeShort:NameEfiRuntimeServicesCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + RTCodePages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiRuntimeServicesData: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiRuntimeServicesDataShort:NameEfiRuntimeServicesData, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + RTDataPages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiConventionalMemory: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiConventionalMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + AvailPages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiPersistentMemory: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPersistentMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + PersistentPages += Walker->NumberOfPages; + TotalPages += Walker->NumberOfPages; + break; + case EfiUnusableMemory: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiUnusableMemoryShort:NameEfiUnusableMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + UnusableMemoryPages += Walker->NumberOfPages; + break; + case EfiACPIReclaimMemory: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIReclaimMemoryShort:NameEfiACPIReclaimMemory, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + TotalPages += Walker->NumberOfPages; + AcpiReclaimPages += Walker->NumberOfPages; + break; + case EfiACPIMemoryNVS: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiACPIMemoryNVSShort:NameEfiACPIMemoryNVS, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + TotalPages += Walker->NumberOfPages; + AcpiNvsPages += Walker->NumberOfPages; + break; + case EfiMemoryMappedIO: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOShort:NameEfiMemoryMappedIO, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + MmioSpacePages += Walker->NumberOfPages; + break; + case EfiMemoryMappedIOPortSpace: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, !Sfo?NameEfiMemoryMappedIOPortSpaceShort:NameEfiMemoryMappedIOPortSpace, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + MmioPortPages += Walker->NumberOfPages; + break; + case EfiPalCode: + ShellPrintHiiEx(-1, -1, NULL, (EFI_STRING_ID)(!Sfo?STRING_TOKEN (STR_MEMMAP_LIST_ITEM):STRING_TOKEN (STR_MEMMAP_LIST_ITEM_SFO)), gShellDebug1HiiHandle, NameEfiPalCode, Walker->PhysicalStart, Walker->PhysicalStart+MultU64x64(SIZE_4KB,Walker->NumberOfPages)-1, Walker->NumberOfPages, Walker->Attribute); + TotalPages += Walker->NumberOfPages; + PalCodePages += Walker->NumberOfPages; + break; + default: + // + // Shell Spec defines the SFO format. + // Do not print the OEM/OS memory usage in the SFO format, to avoid conflict with Shell Spec. + // + if (!Sfo) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_ITEM_OTHER), gShellDebug1HiiHandle, Walker->Type, Walker->PhysicalStart, Walker->PhysicalStart + MultU64x64 (SIZE_4KB, Walker->NumberOfPages) - 1, Walker->NumberOfPages, Walker->Attribute); + } + TotalPages += Walker->NumberOfPages; + AddMemoryLength (&MemoryList, Walker->Type, Walker->NumberOfPages); + break; + } + } + // + // print the summary + // + ReservedPagesSize = MultU64x64(SIZE_4KB,ReservedPages); + LoadCodePagesSize = MultU64x64(SIZE_4KB,LoadCodePages); + LoadDataPagesSize = MultU64x64(SIZE_4KB,LoadDataPages); + BSCodePagesSize = MultU64x64(SIZE_4KB,BSCodePages); + BSDataPagesSize = MultU64x64(SIZE_4KB,BSDataPages); + RTDataPagesSize = MultU64x64(SIZE_4KB,RTDataPages); + RTCodePagesSize = MultU64x64(SIZE_4KB,RTCodePages); + AvailPagesSize = MultU64x64(SIZE_4KB,AvailPages); + TotalPagesSize = MultU64x64(SIZE_4KB,TotalPages); + AcpiReclaimPagesSize = MultU64x64(SIZE_4KB,AcpiReclaimPages); + AcpiNvsPagesSize = MultU64x64(SIZE_4KB,AcpiNvsPages); + MmioSpacePagesSize = MultU64x64(SIZE_4KB,MmioSpacePages); + MmioPortPagesSize = MultU64x64(SIZE_4KB,MmioPortPages); + PalCodePagesSize = MultU64x64(SIZE_4KB,PalCodePages); + PersistentPagesSize = MultU64x64(SIZE_4KB,PersistentPages); + UnusableMemoryPagesSize = MultU64x64(SIZE_4KB,UnusableMemoryPages); + if (!Sfo) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM), gShellDebug1HiiHandle, + ReservedPages, ReservedPagesSize, + LoadCodePages, LoadCodePagesSize, + LoadDataPages, LoadDataPagesSize, + BSCodePages, BSCodePagesSize, + BSDataPages, BSDataPagesSize, + RTCodePages, RTCodePagesSize, + RTDataPages, RTDataPagesSize, + AcpiReclaimPages, AcpiReclaimPagesSize, + AcpiNvsPages, AcpiNvsPagesSize, + MmioSpacePages, MmioSpacePagesSize, + MmioPortPages, MmioPortPagesSize, + PalCodePages, PalCodePagesSize, + AvailPages, AvailPagesSize, + PersistentPages, PersistentPagesSize + ); + + // + // Print out the total memory usage for OEM/OS types in the order of type. + // + for (Link = GetFirstNode (&MemoryList); !IsNull (&MemoryList, Link); Link = GetNextNode (&MemoryList, Link)) { + Entry = BASE_CR (Link, MEMORY_LENGTH_ENTRY, Link); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM_OTHER), gShellDebug1HiiHandle, + Entry->Type, Entry->NumberOfPages, MultU64x64 (SIZE_4KB, Entry->NumberOfPages) + ); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM2), gShellDebug1HiiHandle, + DivU64x32(MultU64x64(SIZE_4KB,TotalPages), SIZE_1MB), TotalPagesSize + ); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MEMMAP_LIST_SUMM_SFO), gShellDebug1HiiHandle, + TotalPagesSize, + ReservedPagesSize, + BSCodePagesSize, + BSDataPagesSize, + RTCodePagesSize, + RTDataPagesSize, + LoadCodePagesSize, + LoadDataPagesSize, + AvailPagesSize, + MmioSpacePagesSize, + MmioPortPagesSize, + UnusableMemoryPagesSize, + AcpiReclaimPagesSize, + AcpiNvsPagesSize, + PalCodePagesSize, + PersistentPagesSize + ); + } + } + } + ShellCommandLineFreeVarList (Package); + } + + if (Descriptors != NULL) { + FreePool(Descriptors); + } + + // + // Free the memory list. + // + for (Link = GetFirstNode (&MemoryList); !IsNull (&MemoryList, Link); ) { + Link = RemoveEntryList (Link); + } + + return (ShellStatus); +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c new file mode 100644 index 00000000..bc5b4ca1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c @@ -0,0 +1,631 @@ +/** @file + Main file for Mm shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Library/ShellLib.h> +#include <Library/IoLib.h> +#include <Protocol/PciRootBridgeIo.h> +#include <Protocol/DeviceIo.h> + +typedef enum { + ShellMmMemory, + ShellMmMemoryMappedIo, + ShellMmIo, + ShellMmPci, + ShellMmPciExpress +} SHELL_MM_ACCESS_TYPE; + +CONST UINT16 mShellMmAccessTypeStr[] = { + STRING_TOKEN (STR_MM_MEM), + STRING_TOKEN (STR_MM_MMIO), + STRING_TOKEN (STR_MM_IO), + STRING_TOKEN (STR_MM_PCI), + STRING_TOKEN (STR_MM_PCIE) +}; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-mmio", TypeFlag}, + {L"-mem", TypeFlag}, + {L"-io", TypeFlag}, + {L"-pci", TypeFlag}, + {L"-pcie", TypeFlag}, + {L"-n", TypeFlag}, + {L"-w", TypeValue}, + {NULL, TypeMax} + }; + +CONST UINT64 mShellMmMaxNumber[] = { + 0, MAX_UINT8, MAX_UINT16, 0, MAX_UINT32, 0, 0, 0, MAX_UINT64 +}; +CONST EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH mShellMmRootBridgeIoWidth[] = { + 0, EfiPciWidthUint8, EfiPciWidthUint16, 0, EfiPciWidthUint32, 0, 0, 0, EfiPciWidthUint64 +}; +CONST EFI_CPU_IO_PROTOCOL_WIDTH mShellMmCpuIoWidth[] = { + 0, EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, 0, EfiCpuIoWidthUint32, 0, 0, 0, EfiCpuIoWidthUint64 +}; + +/** + Extract the PCI segment, bus, device, function, register from + from a PCI or PCIE format of address.. + + @param[in] PciFormat Whether the address is of PCI format of PCIE format. + @param[in] Address PCI or PCIE address. + @param[out] Segment PCI segment number. + @param[out] Bus PCI bus number. + @param[out] Device PCI device number. + @param[out] Function PCI function number. + @param[out] Register PCI register offset. +**/ +VOID +ShellMmDecodePciAddress ( + IN BOOLEAN PciFormat, + IN UINT64 Address, + OUT UINT32 *Segment, + OUT UINT8 *Bus, + OUT UINT8 *Device, OPTIONAL + OUT UINT8 *Function, OPTIONAL + OUT UINT32 *Register OPTIONAL + ) +{ + if (PciFormat) { + // + // PCI Configuration Space.The address will have the format ssssbbddffrr, + // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rr = Register. + // + *Segment = (UINT32) (RShiftU64 (Address, 32) & 0xFFFF); + *Bus = (UINT8) (((UINT32) Address) >> 24); + + if (Device != NULL) { + *Device = (UINT8) (((UINT32) Address) >> 16); + } + if (Function != NULL) { + *Function = (UINT8) (((UINT32) Address) >> 8); + } + if (Register != NULL) { + *Register = (UINT8) Address; + } + } else { + // + // PCI Express Configuration Space.The address will have the format ssssssbbddffrrr, + // where ssss = Segment, bb = Bus, dd = Device, ff = Function and rrr = Register. + // + *Segment = (UINT32) (RShiftU64 (Address, 36) & 0xFFFF); + *Bus = (UINT8) RShiftU64 (Address, 28); + if (Device != NULL) { + *Device = (UINT8) (((UINT32) Address) >> 20); + } + if (Function != NULL) { + *Function = (UINT8) (((UINT32) Address) >> 12); + } + if (Register != NULL) { + *Register = (UINT32) (Address & 0xFFF); + } + } +} + +/** + Read or write some data from or into the Address. + + @param[in] AccessType Access type. + @param[in] PciRootBridgeIo PciRootBridgeIo instance. + @param[in] CpuIo CpuIo instance. + @param[in] Read TRUE for read, FALSE for write. + @param[in] Addresss The memory location to access. + @param[in] Size The size of Buffer in Width sized units. + @param[in, out] Buffer The buffer to read into or write from. +**/ +VOID +ShellMmAccess ( + IN SHELL_MM_ACCESS_TYPE AccessType, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN EFI_CPU_IO2_PROTOCOL *CpuIo, + IN BOOLEAN Read, + IN UINT64 Address, + IN UINTN Size, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM RootBridgeIoMem; + EFI_CPU_IO_PROTOCOL_IO_MEM CpuIoMem; + UINT32 Segment; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT32 Register; + + if (AccessType == ShellMmMemory) { + if (Read) { + CopyMem (Buffer, (VOID *) (UINTN) Address, Size); + } else { + CopyMem ((VOID *) (UINTN) Address, Buffer, Size); + } + } else { + RootBridgeIoMem = NULL; + CpuIoMem = NULL; + switch (AccessType) { + case ShellMmPci: + case ShellMmPciExpress: + ASSERT (PciRootBridgeIo != NULL); + ShellMmDecodePciAddress ((BOOLEAN) (AccessType == ShellMmPci), Address, &Segment, &Bus, &Device, &Function, &Register); + if (Read) { + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, mShellMmRootBridgeIoWidth[Size], + EFI_PCI_ADDRESS (Bus, Device, Function, Register), + 1, Buffer + ); + } else { + Status = PciRootBridgeIo->Pci.Write ( + PciRootBridgeIo, mShellMmRootBridgeIoWidth[Size], + EFI_PCI_ADDRESS (Bus, Device, Function, Register), + 1, Buffer + ); + } + ASSERT_EFI_ERROR (Status); + return; + + case ShellMmMemoryMappedIo: + if (PciRootBridgeIo != NULL) { + RootBridgeIoMem = Read ? PciRootBridgeIo->Mem.Read : PciRootBridgeIo->Mem.Write; + } + if (CpuIo != NULL) { + CpuIoMem = Read ? CpuIo->Mem.Read : CpuIo->Mem.Write; + } + break; + + case ShellMmIo: + if (PciRootBridgeIo != NULL) { + RootBridgeIoMem = Read ? PciRootBridgeIo->Io.Read : PciRootBridgeIo->Io.Write; + } + if (CpuIo != NULL) { + CpuIoMem = Read ? CpuIo->Io.Read : CpuIo->Io.Write; + } + break; + default: + ASSERT (FALSE); + break; + } + + Status = EFI_UNSUPPORTED; + if (RootBridgeIoMem != NULL) { + Status = RootBridgeIoMem (PciRootBridgeIo, mShellMmRootBridgeIoWidth[Size], Address, 1, Buffer); + } + if (EFI_ERROR (Status) && (CpuIoMem != NULL)) { + Status = CpuIoMem (CpuIo, mShellMmCpuIoWidth[Size], Address, 1, Buffer); + } + + if (EFI_ERROR (Status)) { + if (AccessType == ShellMmIo) { + switch (Size) { + case 1: + if (Read) { + *(UINT8 *) Buffer = IoRead8 ((UINTN) Address); + } else { + IoWrite8 ((UINTN) Address, *(UINT8 *) Buffer); + } + break; + case 2: + if (Read) { + *(UINT16 *) Buffer = IoRead16 ((UINTN) Address); + } else { + IoWrite16 ((UINTN) Address, *(UINT16 *) Buffer); + } + break; + case 4: + if (Read) { + *(UINT32 *) Buffer = IoRead32 ((UINTN) Address); + } else { + IoWrite32 ((UINTN) Address, *(UINT32 *) Buffer); + } + break; + case 8: + if (Read) { + *(UINT64 *) Buffer = IoRead64 ((UINTN) Address); + } else { + IoWrite64 ((UINTN) Address, *(UINT64 *) Buffer); + } + break; + default: + ASSERT (FALSE); + break; + } + } else { + switch (Size) { + case 1: + if (Read) { + *(UINT8 *) Buffer = MmioRead8 ((UINTN) Address); + } else { + MmioWrite8 ((UINTN) Address, *(UINT8 *) Buffer); + } + break; + case 2: + if (Read) { + *(UINT16 *) Buffer = MmioRead16 ((UINTN) Address); + } else { + MmioWrite16 ((UINTN) Address, *(UINT16 *) Buffer); + } + break; + case 4: + if (Read) { + *(UINT32 *) Buffer = MmioRead32 ((UINTN) Address); + } else { + MmioWrite32 ((UINTN) Address, *(UINT32 *) Buffer); + } + break; + case 8: + if (Read) { + *(UINT64 *) Buffer = MmioRead64 ((UINTN) Address); + } else { + MmioWrite64 ((UINTN) Address, *(UINT64 *) Buffer); + } + break; + default: + ASSERT (FALSE); + break; + } + } + } + } +} + +/** + Find the CpuIo instance and PciRootBridgeIo instance in the platform. + If there are multiple PciRootBridgeIo instances, the instance which manages + the Address is returned. + + @param[in] AccessType Access type. + @param[in] Address Address to access. + @param[out] CpuIo Return the CpuIo instance. + @param[out] PciRootBridgeIo Return the proper PciRootBridgeIo instance. + + @retval TRUE There are PciRootBridgeIo instances in the platform. + @retval FALSE There isn't PciRootBridgeIo instance in the platform. +**/ +BOOLEAN +ShellMmLocateIoProtocol ( + IN SHELL_MM_ACCESS_TYPE AccessType, + IN UINT64 Address, + OUT EFI_CPU_IO2_PROTOCOL **CpuIo, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **PciRootBridgeIo + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Io; + UINT32 Segment; + UINT8 Bus; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) CpuIo); + if (EFI_ERROR (Status)) { + *CpuIo = NULL; + } + + *PciRootBridgeIo = NULL; + HandleBuffer = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) { + return FALSE; + } + + Segment = 0; + Bus = 0; + if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) { + ShellMmDecodePciAddress ((BOOLEAN) (AccessType == ShellMmPci), Address, &Segment, &Bus, NULL, NULL, NULL); + } + + // + // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment & bus number + // + for (Index = 0; (Index < HandleCount) && (*PciRootBridgeIo == NULL); Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciRootBridgeIoProtocolGuid, + (VOID *) &Io + ); + if (EFI_ERROR (Status)) { + continue; + } + + if ((((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) && (Io->SegmentNumber == Segment)) || + ((AccessType == ShellMmIo) || (AccessType == ShellMmMemoryMappedIo)) + ) { + Status = Io->Configuration (Io, (VOID **) &Descriptors); + if (!EFI_ERROR (Status)) { + while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) { + // + // Compare the segment and bus range for PCI/PCIE access + // + if ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) && + ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) && + ((Bus >= Descriptors->AddrRangeMin) && (Bus <= Descriptors->AddrRangeMax)) + ) { + *PciRootBridgeIo = Io; + break; + + // + // Compare the address range for MMIO/IO access + // + } else if ((((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) && (AccessType == ShellMmIo)) || + ((Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) && (AccessType == ShellMmMemoryMappedIo)) + ) && ((Address >= Descriptors->AddrRangeMin) && (Address <= Descriptors->AddrRangeMax)) + ) { + *PciRootBridgeIo = Io; + break; + } + Descriptors++; + } + } + } + } + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return TRUE; +} + +/** + Function for 'mm' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_CPU_IO2_PROTOCOL *CpuIo; + UINT64 Address; + UINT64 Value; + SHELL_MM_ACCESS_TYPE AccessType; + UINT64 Buffer; + UINTN Index; + UINTN Size; + BOOLEAN Complete; + CHAR16 *InputStr; + BOOLEAN Interactive; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Temp; + BOOLEAN HasPciRootBridgeIo; + + Value = 0; + Address = 0; + ShellStatus = SHELL_SUCCESS; + InputStr = NULL; + Size = 1; + AccessType = ShellMmMemory; + + // + // Parse arguments + // + 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), gShellDebug1HiiHandle, L"mm", ProblemParam); + FreePool (ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } else { + ASSERT (FALSE); + } + } else { + if (ShellCommandLineGetCount (Package) < 2) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } else if (ShellCommandLineGetCount (Package) > 3) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } else if (ShellCommandLineGetFlag (Package, L"-w") && ShellCommandLineGetValue (Package, L"-w") == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"mm", L"-w"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } else { + if (ShellCommandLineGetFlag (Package, L"-mmio")) { + AccessType = ShellMmMemoryMappedIo; + if (ShellCommandLineGetFlag (Package, L"-mem") + || ShellCommandLineGetFlag (Package, L"-io") + || ShellCommandLineGetFlag (Package, L"-pci") + || ShellCommandLineGetFlag (Package, L"-pcie") + ) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } else if (ShellCommandLineGetFlag (Package, L"-mem")) { + AccessType = ShellMmMemory; + if (ShellCommandLineGetFlag (Package, L"-io") + || ShellCommandLineGetFlag (Package, L"-pci") + || ShellCommandLineGetFlag (Package, L"-pcie") + ) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } else if (ShellCommandLineGetFlag (Package, L"-io")) { + AccessType = ShellMmIo; + if (ShellCommandLineGetFlag (Package, L"-pci") + || ShellCommandLineGetFlag (Package, L"-pcie") + ) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } else if (ShellCommandLineGetFlag (Package, L"-pci")) { + AccessType = ShellMmPci; + if (ShellCommandLineGetFlag (Package, L"-pcie") + ) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } else if (ShellCommandLineGetFlag (Package, L"-pcie")) { + AccessType = ShellMmPciExpress; + } + } + + // + // Non interactive for a script file or for the specific parameter + // + Interactive = TRUE; + if (gEfiShellProtocol->BatchIsActive () || ShellCommandLineGetFlag (Package, L"-n")) { + Interactive = FALSE; + } + + Temp = ShellCommandLineGetValue (Package, L"-w"); + if (Temp != NULL) { + Size = ShellStrToUintn (Temp); + } + if ((Size != 1) && (Size != 2) && (Size != 4) && (Size != 8)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"mm", Temp, L"-w"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + Temp = ShellCommandLineGetRawValue (Package, 1); + Status = ShellConvertStringToUint64 (Temp, &Address, TRUE, FALSE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if ((Address & (Size - 1)) != 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, L"mm", Address); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + // + // locate IO protocol interface + // + HasPciRootBridgeIo = ShellMmLocateIoProtocol (AccessType, Address, &CpuIo, &PciRootBridgeIo); + if ((AccessType == ShellMmPci) || (AccessType == ShellMmPciExpress)) { + if (!HasPciRootBridgeIo) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"mm"); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + if (PciRootBridgeIo == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE_ADDRESS_RANGE), gShellDebug1HiiHandle, L"mm", Address); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + + // + // Mode 1: Directly set a value + // + Temp = ShellCommandLineGetRawValue (Package, 2); + if (Temp != NULL) { + Status = ShellConvertStringToUint64 (Temp, &Value, TRUE, FALSE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if (Value > mShellMmMaxNumber[Size]) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mm", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Value); + goto Done; + } + + // + // Mode 2: Directly show a value + // + if (!Interactive) { + if (!gEfiShellProtocol->BatchIsActive ()) { + ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle); + } + ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer); + + if (!gEfiShellProtocol->BatchIsActive ()) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address); + } + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]); + ShellPrintEx (-1, -1, L"\r\n"); + goto Done; + } + + // + // Mode 3: Show or set values in interactive mode + // + Complete = FALSE; + do { + ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, TRUE, Address, Size, &Buffer); + ShellPrintHiiEx (-1, -1, NULL, mShellMmAccessTypeStr[AccessType], gShellDebug1HiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_BUF), gShellDebug1HiiHandle, Size * 2, Buffer & mShellMmMaxNumber[Size]); + ShellPrintEx (-1, -1, L" > "); + // + // wait user input to modify + // + if (InputStr != NULL) { + FreePool (InputStr); + InputStr = NULL; + } + ShellPromptForResponse (ShellPromptResponseTypeFreeform, NULL, (VOID**) &InputStr); + + if (InputStr != NULL) { + // + // skip space characters + // + for (Index = 0; InputStr[Index] == ' '; Index++); + + if (InputStr[Index] != CHAR_NULL) { + if ((InputStr[Index] == '.') || (InputStr[Index] == 'q') || (InputStr[Index] == 'Q')) { + Complete = TRUE; + } else if (!EFI_ERROR (ShellConvertStringToUint64 (InputStr + Index, &Buffer, TRUE, TRUE)) && + (Buffer <= mShellMmMaxNumber[Size]) + ) { + ShellMmAccess (AccessType, PciRootBridgeIo, CpuIo, FALSE, Address, Size, &Buffer); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle, L"mm"); + continue; + } + } + } + + Address += Size; + ShellPrintEx (-1, -1, L"\r\n"); + } while (!Complete); + } + ASSERT (ShellStatus == SHELL_SUCCESS); + +Done: + if (InputStr != NULL) { + FreePool (InputStr); + } + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + return ShellStatus; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mode.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mode.c new file mode 100644 index 00000000..ef093da6 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Mode.c @@ -0,0 +1,122 @@ +/** @file + Main file for Mode shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" + +/** + Function for 'mode' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMode ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + UINTN NewCol; + UINTN NewRow; + UINTN Col; + UINTN Row; + CONST CHAR16 *Temp; + BOOLEAN Done; + INT32 LoopVar; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"mode", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"mode"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) == 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"mode"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) == 3) { + Temp = ShellCommandLineGetRawValue(Package, 1); + if (!ShellIsHexOrDecimalNumber(Temp, FALSE, FALSE)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + } + NewCol = ShellStrToUintn(Temp); + Temp = ShellCommandLineGetRawValue(Package, 2); + if (!ShellIsHexOrDecimalNumber(Temp, FALSE, FALSE)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"mode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + } + NewRow = ShellStrToUintn(Temp); + + for (LoopVar = 0, Done = FALSE; LoopVar < gST->ConOut->Mode->MaxMode && ShellStatus == SHELL_SUCCESS ; LoopVar++) { + Status = gST->ConOut->QueryMode(gST->ConOut, LoopVar, &Col, &Row); + if (EFI_ERROR(Status)) { + continue; + } + if (Col == NewCol && Row == NewRow) { + Status = gST->ConOut->SetMode(gST->ConOut, LoopVar); + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MODE_SET_FAIL), gShellDebug1HiiHandle, L"mode"); + ShellStatus = SHELL_DEVICE_ERROR; + } else { + // worked fine... + Done = TRUE; + } + break; + } + } + + if (!Done) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MODE_NO_MATCH), gShellDebug1HiiHandle, L"mode"); + ShellStatus = SHELL_INVALID_PARAMETER; + } + + } else if (ShellCommandLineGetCount(Package) == 1) { + // + // print out valid + // + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MODE_LIST_HEAD), gShellDebug1HiiHandle); + for (LoopVar = 0, Done = FALSE; LoopVar < gST->ConOut->Mode->MaxMode && ShellStatus == SHELL_SUCCESS ; LoopVar++) { + Status = gST->ConOut->QueryMode(gST->ConOut, LoopVar, &Col, &Row); + if (EFI_ERROR(Status)) { + continue; + } + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MODE_LIST_ITEM), gShellDebug1HiiHandle, Col, Row, LoopVar == gST->ConOut->Mode->Mode?L'*':L' '); + } + } + ShellCommandLineFreeVarList (Package); + } + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c new file mode 100644 index 00000000..6cb5cf23 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c @@ -0,0 +1,5815 @@ +/** @file + Main file for Pci shell Debug1 function. + + Copyright (c) 2005 - 2021, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Protocol/PciRootBridgeIo.h> +#include <Library/ShellLib.h> +#include <IndustryStandard/Pci.h> +#include <IndustryStandard/Acpi.h> +#include "Pci.h" + +// +// Printable strings for Pci class code +// +typedef struct { + CHAR16 *BaseClass; // Pointer to the PCI base class string + CHAR16 *SubClass; // Pointer to the PCI sub class string + CHAR16 *PIFClass; // Pointer to the PCI programming interface string +} PCI_CLASS_STRINGS; + +// +// a structure holding a single entry, which also points to its lower level +// class +// +typedef struct PCI_CLASS_ENTRY_TAG { + UINT8 Code; // Class, subclass or I/F code + CHAR16 *DescText; // Description string + struct PCI_CLASS_ENTRY_TAG *LowerLevelClass; // Subclass or I/F if any +} PCI_CLASS_ENTRY; + +// +// Declarations of entries which contain printable strings for class codes +// in PCI configuration space +// +PCI_CLASS_ENTRY PCIBlankEntry[]; +PCI_CLASS_ENTRY PCISubClass_00[]; +PCI_CLASS_ENTRY PCISubClass_01[]; +PCI_CLASS_ENTRY PCISubClass_02[]; +PCI_CLASS_ENTRY PCISubClass_03[]; +PCI_CLASS_ENTRY PCISubClass_04[]; +PCI_CLASS_ENTRY PCISubClass_05[]; +PCI_CLASS_ENTRY PCISubClass_06[]; +PCI_CLASS_ENTRY PCISubClass_07[]; +PCI_CLASS_ENTRY PCISubClass_08[]; +PCI_CLASS_ENTRY PCISubClass_09[]; +PCI_CLASS_ENTRY PCISubClass_0a[]; +PCI_CLASS_ENTRY PCISubClass_0b[]; +PCI_CLASS_ENTRY PCISubClass_0c[]; +PCI_CLASS_ENTRY PCISubClass_0d[]; +PCI_CLASS_ENTRY PCISubClass_0e[]; +PCI_CLASS_ENTRY PCISubClass_0f[]; +PCI_CLASS_ENTRY PCISubClass_10[]; +PCI_CLASS_ENTRY PCISubClass_11[]; +PCI_CLASS_ENTRY PCISubClass_12[]; +PCI_CLASS_ENTRY PCISubClass_13[]; +PCI_CLASS_ENTRY PCIPIFClass_0100[]; +PCI_CLASS_ENTRY PCIPIFClass_0101[]; +PCI_CLASS_ENTRY PCIPIFClass_0105[]; +PCI_CLASS_ENTRY PCIPIFClass_0106[]; +PCI_CLASS_ENTRY PCIPIFClass_0107[]; +PCI_CLASS_ENTRY PCIPIFClass_0108[]; +PCI_CLASS_ENTRY PCIPIFClass_0109[]; +PCI_CLASS_ENTRY PCIPIFClass_0300[]; +PCI_CLASS_ENTRY PCIPIFClass_0604[]; +PCI_CLASS_ENTRY PCIPIFClass_0609[]; +PCI_CLASS_ENTRY PCIPIFClass_060b[]; +PCI_CLASS_ENTRY PCIPIFClass_0700[]; +PCI_CLASS_ENTRY PCIPIFClass_0701[]; +PCI_CLASS_ENTRY PCIPIFClass_0703[]; +PCI_CLASS_ENTRY PCIPIFClass_0800[]; +PCI_CLASS_ENTRY PCIPIFClass_0801[]; +PCI_CLASS_ENTRY PCIPIFClass_0802[]; +PCI_CLASS_ENTRY PCIPIFClass_0803[]; +PCI_CLASS_ENTRY PCIPIFClass_0904[]; +PCI_CLASS_ENTRY PCIPIFClass_0c00[]; +PCI_CLASS_ENTRY PCIPIFClass_0c03[]; +PCI_CLASS_ENTRY PCIPIFClass_0c07[]; +PCI_CLASS_ENTRY PCIPIFClass_0d01[]; +PCI_CLASS_ENTRY PCIPIFClass_0e00[]; + +// +// Base class strings entries +// +PCI_CLASS_ENTRY gClassStringList[] = { + { + 0x00, + L"Pre 2.0 device", + PCISubClass_00 + }, + { + 0x01, + L"Mass Storage Controller", + PCISubClass_01 + }, + { + 0x02, + L"Network Controller", + PCISubClass_02 + }, + { + 0x03, + L"Display Controller", + PCISubClass_03 + }, + { + 0x04, + L"Multimedia Device", + PCISubClass_04 + }, + { + 0x05, + L"Memory Controller", + PCISubClass_05 + }, + { + 0x06, + L"Bridge Device", + PCISubClass_06 + }, + { + 0x07, + L"Simple Communications Controllers", + PCISubClass_07 + }, + { + 0x08, + L"Base System Peripherals", + PCISubClass_08 + }, + { + 0x09, + L"Input Devices", + PCISubClass_09 + }, + { + 0x0a, + L"Docking Stations", + PCISubClass_0a + }, + { + 0x0b, + L"Processors", + PCISubClass_0b + }, + { + 0x0c, + L"Serial Bus Controllers", + PCISubClass_0c + }, + { + 0x0d, + L"Wireless Controllers", + PCISubClass_0d + }, + { + 0x0e, + L"Intelligent IO Controllers", + PCISubClass_0e + }, + { + 0x0f, + L"Satellite Communications Controllers", + PCISubClass_0f + }, + { + 0x10, + L"Encryption/Decryption Controllers", + PCISubClass_10 + }, + { + 0x11, + L"Data Acquisition & Signal Processing Controllers", + PCISubClass_11 + }, + { + 0x12, + L"Processing Accelerators", + PCISubClass_12 + }, + { + 0x13, + L"Non-Essential Instrumentation", + PCISubClass_13 + }, + { + 0xff, + L"Device does not fit in any defined classes", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +// +// Subclass strings entries +// +PCI_CLASS_ENTRY PCIBlankEntry[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_00[] = { + { + 0x00, + L"All devices other than VGA", + PCIBlankEntry + }, + { + 0x01, + L"VGA-compatible devices", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_01[] = { + { + 0x00, + L"SCSI", + PCIPIFClass_0100 + }, + { + 0x01, + L"IDE controller", + PCIPIFClass_0101 + }, + { + 0x02, + L"Floppy disk controller", + PCIBlankEntry + }, + { + 0x03, + L"IPI controller", + PCIBlankEntry + }, + { + 0x04, + L"RAID controller", + PCIBlankEntry + }, + { + 0x05, + L"ATA controller with ADMA interface", + PCIPIFClass_0105 + }, + { + 0x06, + L"Serial ATA controller", + PCIPIFClass_0106 + }, + { + 0x07, + L"Serial Attached SCSI (SAS) controller ", + PCIPIFClass_0107 + }, + { + 0x08, + L"Non-volatile memory subsystem", + PCIPIFClass_0108 + }, + { + 0x09, + L"Universal Flash Storage (UFS) controller ", + PCIPIFClass_0109 + }, + { + 0x80, + L"Other mass storage controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_02[] = { + { + 0x00, + L"Ethernet controller", + PCIBlankEntry + }, + { + 0x01, + L"Token ring controller", + PCIBlankEntry + }, + { + 0x02, + L"FDDI controller", + PCIBlankEntry + }, + { + 0x03, + L"ATM controller", + PCIBlankEntry + }, + { + 0x04, + L"ISDN controller", + PCIBlankEntry + }, + { + 0x05, + L"WorldFip controller", + PCIBlankEntry + }, + { + 0x06, + L"PICMG 2.14 Multi Computing", + PCIBlankEntry + }, + { + 0x07, + L"InfiniBand controller", + PCIBlankEntry + }, + { + 0x80, + L"Other network controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_03[] = { + { + 0x00, + L"VGA/8514 controller", + PCIPIFClass_0300 + }, + { + 0x01, + L"XGA controller", + PCIBlankEntry + }, + { + 0x02, + L"3D controller", + PCIBlankEntry + }, + { + 0x80, + L"Other display controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */PCIBlankEntry + } +}; + +PCI_CLASS_ENTRY PCISubClass_04[] = { + { + 0x00, + L"Video device", + PCIBlankEntry + }, + { + 0x01, + L"Audio device", + PCIBlankEntry + }, + { + 0x02, + L"Computer Telephony device", + PCIBlankEntry + }, + { + 0x03, + L"Mixed mode device", + PCIBlankEntry + }, + { + 0x80, + L"Other multimedia device", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_05[] = { + { + 0x00, + L"RAM memory controller", + PCIBlankEntry + }, + { + 0x01, + L"Flash memory controller", + PCIBlankEntry + }, + { + 0x80, + L"Other memory controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_06[] = { + { + 0x00, + L"Host/PCI bridge", + PCIBlankEntry + }, + { + 0x01, + L"PCI/ISA bridge", + PCIBlankEntry + }, + { + 0x02, + L"PCI/EISA bridge", + PCIBlankEntry + }, + { + 0x03, + L"PCI/Micro Channel bridge", + PCIBlankEntry + }, + { + 0x04, + L"PCI/PCI bridge", + PCIPIFClass_0604 + }, + { + 0x05, + L"PCI/PCMCIA bridge", + PCIBlankEntry + }, + { + 0x06, + L"NuBus bridge", + PCIBlankEntry + }, + { + 0x07, + L"CardBus bridge", + PCIBlankEntry + }, + { + 0x08, + L"RACEway bridge", + PCIBlankEntry + }, + { + 0x09, + L"Semi-transparent PCI-to-PCI bridge", + PCIPIFClass_0609 + }, + { + 0x0A, + L"InfiniBand-to-PCI host bridge", + PCIBlankEntry + }, + { + 0x0B, + L"Advanced Switching to PCI host bridge", + PCIPIFClass_060b + }, + { + 0x80, + L"Other bridge type", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_07[] = { + { + 0x00, + L"Serial controller", + PCIPIFClass_0700 + }, + { + 0x01, + L"Parallel port", + PCIPIFClass_0701 + }, + { + 0x02, + L"Multiport serial controller", + PCIBlankEntry + }, + { + 0x03, + L"Modem", + PCIPIFClass_0703 + }, + { + 0x04, + L"GPIB (IEEE 488.1/2) controller", + PCIBlankEntry + }, + { + 0x05, + L"Smart Card", + PCIBlankEntry + }, + { + 0x80, + L"Other communication device", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_08[] = { + { + 0x00, + L"PIC", + PCIPIFClass_0800 + }, + { + 0x01, + L"DMA controller", + PCIPIFClass_0801 + }, + { + 0x02, + L"System timer", + PCIPIFClass_0802 + }, + { + 0x03, + L"RTC controller", + PCIPIFClass_0803 + }, + { + 0x04, + L"Generic PCI Hot-Plug controller", + PCIBlankEntry + }, + { + 0x05, + L"SD Host controller", + PCIBlankEntry + }, + { + 0x06, + L"IOMMU", + PCIBlankEntry + }, + { + 0x07, + L"Root Complex Event Collector", + PCIBlankEntry + }, + { + 0x80, + L"Other system peripheral", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_09[] = { + { + 0x00, + L"Keyboard controller", + PCIBlankEntry + }, + { + 0x01, + L"Digitizer (pen)", + PCIBlankEntry + }, + { + 0x02, + L"Mouse controller", + PCIBlankEntry + }, + { + 0x03, + L"Scanner controller", + PCIBlankEntry + }, + { + 0x04, + L"Gameport controller", + PCIPIFClass_0904 + }, + { + 0x80, + L"Other input controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0a[] = { + { + 0x00, + L"Generic docking station", + PCIBlankEntry + }, + { + 0x80, + L"Other type of docking station", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0b[] = { + { + 0x00, + L"386", + PCIBlankEntry + }, + { + 0x01, + L"486", + PCIBlankEntry + }, + { + 0x02, + L"Pentium", + PCIBlankEntry + }, + { + 0x10, + L"Alpha", + PCIBlankEntry + }, + { + 0x20, + L"PowerPC", + PCIBlankEntry + }, + { + 0x30, + L"MIPS", + PCIBlankEntry + }, + { + 0x40, + L"Co-processor", + PCIBlankEntry + }, + { + 0x80, + L"Other processor", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0c[] = { + { + 0x00, + L"IEEE 1394", + PCIPIFClass_0c00 + }, + { + 0x01, + L"ACCESS.bus", + PCIBlankEntry + }, + { + 0x02, + L"SSA", + PCIBlankEntry + }, + { + 0x03, + L"USB", + PCIPIFClass_0c03 + }, + { + 0x04, + L"Fibre Channel", + PCIBlankEntry + }, + { + 0x05, + L"System Management Bus", + PCIBlankEntry + }, + { + 0x06, + L"InfiniBand", + PCIBlankEntry + }, + { + 0x07, + L"IPMI", + PCIPIFClass_0c07 + }, + { + 0x08, + L"SERCOS Interface Standard (IEC 61491)", + PCIBlankEntry + }, + { + 0x09, + L"CANbus", + PCIBlankEntry + }, + { + 0x80, + L"Other bus type", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0d[] = { + { + 0x00, + L"iRDA compatible controller", + PCIBlankEntry + }, + { + 0x01, + L"", + PCIPIFClass_0d01 + }, + { + 0x10, + L"RF controller", + PCIBlankEntry + }, + { + 0x11, + L"Bluetooth", + PCIBlankEntry + }, + { + 0x12, + L"Broadband", + PCIBlankEntry + }, + { + 0x20, + L"Ethernet (802.11a - 5 GHz)", + PCIBlankEntry + }, + { + 0x21, + L"Ethernet (802.11b - 2.4 GHz)", + PCIBlankEntry + }, + { + 0x80, + L"Other type of wireless controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0e[] = { + { + 0x00, + L"I2O Architecture", + PCIPIFClass_0e00 + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_0f[] = { + { + 0x01, + L"TV", + PCIBlankEntry + }, + { + 0x02, + L"Audio", + PCIBlankEntry + }, + { + 0x03, + L"Voice", + PCIBlankEntry + }, + { + 0x04, + L"Data", + PCIBlankEntry + }, + { + 0x80, + L"Other satellite communication controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_10[] = { + { + 0x00, + L"Network & computing Encrypt/Decrypt", + PCIBlankEntry + }, + { + 0x01, + L"Entertainment Encrypt/Decrypt", + PCIBlankEntry + }, + { + 0x80, + L"Other Encrypt/Decrypt", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_11[] = { + { + 0x00, + L"DPIO modules", + PCIBlankEntry + }, + { + 0x01, + L"Performance Counters", + PCIBlankEntry + }, + { + 0x10, + L"Communications synchronization plus time and frequency test/measurement ", + PCIBlankEntry + }, + { + 0x20, + L"Management card", + PCIBlankEntry + }, + { + 0x80, + L"Other DAQ & SP controllers", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_12[] = { + { + 0x00, + L"Processing Accelerator", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCISubClass_13[] = { + { + 0x00, + L"Non-Essential Instrumentation Function", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +// +// Programming Interface entries +// +PCI_CLASS_ENTRY PCIPIFClass_0100[] = { + { + 0x00, + L"SCSI controller", + PCIBlankEntry + }, + { + 0x11, + L"SCSI storage device SOP using PQI", + PCIBlankEntry + }, + { + 0x12, + L"SCSI controller SOP using PQI", + PCIBlankEntry + }, + { + 0x13, + L"SCSI storage device and controller SOP using PQI", + PCIBlankEntry + }, + { + 0x21, + L"SCSI storage device SOP using NVMe", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0101[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"OM-primary", + PCIBlankEntry + }, + { + 0x02, + L"PI-primary", + PCIBlankEntry + }, + { + 0x03, + L"OM/PI-primary", + PCIBlankEntry + }, + { + 0x04, + L"OM-secondary", + PCIBlankEntry + }, + { + 0x05, + L"OM-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x06, + L"PI-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x07, + L"OM/PI-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x08, + L"OM-secondary", + PCIBlankEntry + }, + { + 0x09, + L"OM-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x0a, + L"PI-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x0b, + L"OM/PI-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x0c, + L"OM-secondary", + PCIBlankEntry + }, + { + 0x0d, + L"OM-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x0e, + L"PI-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x0f, + L"OM/PI-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x80, + L"Master", + PCIBlankEntry + }, + { + 0x81, + L"Master, OM-primary", + PCIBlankEntry + }, + { + 0x82, + L"Master, PI-primary", + PCIBlankEntry + }, + { + 0x83, + L"Master, OM/PI-primary", + PCIBlankEntry + }, + { + 0x84, + L"Master, OM-secondary", + PCIBlankEntry + }, + { + 0x85, + L"Master, OM-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x86, + L"Master, PI-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x87, + L"Master, OM/PI-primary, OM-secondary", + PCIBlankEntry + }, + { + 0x88, + L"Master, OM-secondary", + PCIBlankEntry + }, + { + 0x89, + L"Master, OM-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x8a, + L"Master, PI-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x8b, + L"Master, OM/PI-primary, PI-secondary", + PCIBlankEntry + }, + { + 0x8c, + L"Master, OM-secondary", + PCIBlankEntry + }, + { + 0x8d, + L"Master, OM-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x8e, + L"Master, PI-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x8f, + L"Master, OM/PI-primary, OM/PI-secondary", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0105[] = { + { + 0x20, + L"Single stepping", + PCIBlankEntry + }, + { + 0x30, + L"Continuous operation", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0106[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"AHCI", + PCIBlankEntry + }, + { + 0x02, + L"Serial Storage Bus", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0107[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"Obsolete", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0108[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"NVMHCI", + PCIBlankEntry + }, + { + 0x02, + L"NVM Express", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0109[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"UFSHCI", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0300[] = { + { + 0x00, + L"VGA compatible", + PCIBlankEntry + }, + { + 0x01, + L"8514 compatible", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0604[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"Subtractive decode", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0609[] = { + { + 0x40, + L"Primary PCI bus side facing the system host processor", + PCIBlankEntry + }, + { + 0x80, + L"Secondary PCI bus side facing the system host processor", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_060b[] = { + { + 0x00, + L"Custom", + PCIBlankEntry + }, + { + 0x01, + L"ASI-SIG Defined Portal", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0700[] = { + { + 0x00, + L"Generic XT-compatible", + PCIBlankEntry + }, + { + 0x01, + L"16450-compatible", + PCIBlankEntry + }, + { + 0x02, + L"16550-compatible", + PCIBlankEntry + }, + { + 0x03, + L"16650-compatible", + PCIBlankEntry + }, + { + 0x04, + L"16750-compatible", + PCIBlankEntry + }, + { + 0x05, + L"16850-compatible", + PCIBlankEntry + }, + { + 0x06, + L"16950-compatible", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0701[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x01, + L"Bi-directional", + PCIBlankEntry + }, + { + 0x02, + L"ECP 1.X-compliant", + PCIBlankEntry + }, + { + 0x03, + L"IEEE 1284", + PCIBlankEntry + }, + { + 0xfe, + L"IEEE 1284 target (not a controller)", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0703[] = { + { + 0x00, + L"Generic", + PCIBlankEntry + }, + { + 0x01, + L"Hayes-compatible 16450", + PCIBlankEntry + }, + { + 0x02, + L"Hayes-compatible 16550", + PCIBlankEntry + }, + { + 0x03, + L"Hayes-compatible 16650", + PCIBlankEntry + }, + { + 0x04, + L"Hayes-compatible 16750", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0800[] = { + { + 0x00, + L"Generic 8259", + PCIBlankEntry + }, + { + 0x01, + L"ISA", + PCIBlankEntry + }, + { + 0x02, + L"EISA", + PCIBlankEntry + }, + { + 0x10, + L"IO APIC", + PCIBlankEntry + }, + { + 0x20, + L"IO(x) APIC interrupt controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0801[] = { + { + 0x00, + L"Generic 8237", + PCIBlankEntry + }, + { + 0x01, + L"ISA", + PCIBlankEntry + }, + { + 0x02, + L"EISA", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0802[] = { + { + 0x00, + L"Generic 8254", + PCIBlankEntry + }, + { + 0x01, + L"ISA", + PCIBlankEntry + }, + { + 0x02, + L"EISA", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0803[] = { + { + 0x00, + L"Generic", + PCIBlankEntry + }, + { + 0x01, + L"ISA", + PCIBlankEntry + }, + { + 0x02, + L"EISA", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0904[] = { + { + 0x00, + L"Generic", + PCIBlankEntry + }, + { + 0x10, + L"", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0c00[] = { + { + 0x00, + L"", + PCIBlankEntry + }, + { + 0x10, + L"Using 1394 OpenHCI spec", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0c03[] = { + { + 0x00, + L"UHCI", + PCIBlankEntry + }, + { + 0x10, + L"OHCI", + PCIBlankEntry + }, + { + 0x20, + L"EHCI", + PCIBlankEntry + }, + { + 0x30, + L"xHCI", + PCIBlankEntry + }, + { + 0x80, + L"No specific programming interface", + PCIBlankEntry + }, + { + 0xfe, + L"(Not Host Controller)", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0c07[] = { + { + 0x00, + L"SMIC", + PCIBlankEntry + }, + { + 0x01, + L"Keyboard Controller Style", + PCIBlankEntry + }, + { + 0x02, + L"Block Transfer", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0d01[] = { + { + 0x00, + L"Consumer IR controller", + PCIBlankEntry + }, + { + 0x10, + L"UWB Radio controller", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + +PCI_CLASS_ENTRY PCIPIFClass_0e00[] = { + { + 0x00, + L"Message FIFO at offset 40h", + PCIBlankEntry + }, + { + 0x01, + L"", + PCIBlankEntry + }, + { + 0x00, + NULL, + /* null string ends the list */NULL + } +}; + + +/** + Generates printable Unicode strings that represent PCI device class, + subclass and programmed I/F based on a value passed to the function. + + @param[in] ClassCode Value representing the PCI "Class Code" register read from a + PCI device. The encodings are: + bits 23:16 - Base Class Code + bits 15:8 - Sub-Class Code + bits 7:0 - Programming Interface + @param[in, out] ClassStrings Pointer of PCI_CLASS_STRINGS structure, which contains + printable class strings corresponding to ClassCode. The + caller must not modify the strings that are pointed by + the fields in ClassStrings. +**/ +VOID +PciGetClassStrings ( + IN UINT32 ClassCode, + IN OUT PCI_CLASS_STRINGS *ClassStrings + ) +{ + INTN Index; + UINT8 Code; + PCI_CLASS_ENTRY *CurrentClass; + + // + // Assume no strings found + // + ClassStrings->BaseClass = L"UNDEFINED"; + ClassStrings->SubClass = L"UNDEFINED"; + ClassStrings->PIFClass = L"UNDEFINED"; + + CurrentClass = gClassStringList; + Code = (UINT8) (ClassCode >> 16); + Index = 0; + + // + // Go through all entries of the base class, until the entry with a matching + // base class code is found. If reaches an entry with a null description + // text, the last entry is met, which means no text for the base class was + // found, so no more action is needed. + // + while (Code != CurrentClass[Index].Code) { + if (NULL == CurrentClass[Index].DescText) { + return ; + } + + Index++; + } + // + // A base class was found. Assign description, and check if this class has + // sub-class defined. If sub-class defined, no more action is needed, + // otherwise, continue to find description for the sub-class code. + // + ClassStrings->BaseClass = CurrentClass[Index].DescText; + if (NULL == CurrentClass[Index].LowerLevelClass) { + return ; + } + // + // find Subclass entry + // + CurrentClass = CurrentClass[Index].LowerLevelClass; + Code = (UINT8) (ClassCode >> 8); + Index = 0; + + // + // Go through all entries of the sub-class, until the entry with a matching + // sub-class code is found. If reaches an entry with a null description + // text, the last entry is met, which means no text for the sub-class was + // found, so no more action is needed. + // + while (Code != CurrentClass[Index].Code) { + if (NULL == CurrentClass[Index].DescText) { + return ; + } + + Index++; + } + // + // A class was found for the sub-class code. Assign description, and check if + // this sub-class has programming interface defined. If no, no more action is + // needed, otherwise, continue to find description for the programming + // interface. + // + ClassStrings->SubClass = CurrentClass[Index].DescText; + if (NULL == CurrentClass[Index].LowerLevelClass) { + return ; + } + // + // Find programming interface entry + // + CurrentClass = CurrentClass[Index].LowerLevelClass; + Code = (UINT8) ClassCode; + Index = 0; + + // + // Go through all entries of the I/F entries, until the entry with a + // matching I/F code is found. If reaches an entry with a null description + // text, the last entry is met, which means no text was found, so no more + // action is needed. + // + while (Code != CurrentClass[Index].Code) { + if (NULL == CurrentClass[Index].DescText) { + return ; + } + + Index++; + } + // + // A class was found for the I/F code. Assign description, done! + // + ClassStrings->PIFClass = CurrentClass[Index].DescText; + return ; +} + +/** + Print strings that represent PCI device class, subclass and programmed I/F. + + @param[in] ClassCodePtr Points to the memory which stores register Class Code in PCI + configuration space. + @param[in] IncludePIF If the printed string should include the programming I/F part +**/ +VOID +PciPrintClassCode ( + IN UINT8 *ClassCodePtr, + IN BOOLEAN IncludePIF + ) +{ + UINT32 ClassCode; + PCI_CLASS_STRINGS ClassStrings; + + ClassCode = 0; + ClassCode |= (UINT32)ClassCodePtr[0]; + ClassCode |= (UINT32)(ClassCodePtr[1] << 8); + ClassCode |= (UINT32)(ClassCodePtr[2] << 16); + + // + // Get name from class code + // + PciGetClassStrings (ClassCode, &ClassStrings); + + if (IncludePIF) { + // + // Print base class, sub class, and programming inferface name + // + ShellPrintEx (-1, -1, L"%s - %s - %s", + ClassStrings.BaseClass, + ClassStrings.SubClass, + ClassStrings.PIFClass + ); + + } else { + // + // Only print base class and sub class name + // + ShellPrintEx (-1, -1, L"%s - %s", + ClassStrings.BaseClass, + ClassStrings.SubClass + ); + } +} + +/** + This function finds out the protocol which is in charge of the given + segment, and its bus range covers the current bus number. It lookes + each instances of RootBridgeIoProtocol handle, until the one meets the + criteria is found. + + @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. + @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. + @param[in] Segment Segment number of device we are dealing with. + @param[in] Bus Bus number of device we are dealing with. + @param[out] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +PciFindProtocolInterface ( + IN EFI_HANDLE *HandleBuf, + IN UINTN HandleCount, + IN UINT16 Segment, + IN UINT16 Bus, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev + ); + +/** + This function gets the protocol interface from the given handle, and + obtains its address space descriptors. + + @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle. + @param[out] IoDev Handle used to access configuration space of PCI device. + @param[out] Descriptors Points to the address space descriptors. + + @retval EFI_SUCCESS The command completed successfully +**/ +EFI_STATUS +PciGetProtocolAndResource ( + IN EFI_HANDLE Handle, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, + OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors + ); + +/** + This function get the next bus range of given address space descriptors. + It also moves the pointer backward a node, to get prepared to be called + again. + + @param[in, out] Descriptors Points to current position of a serial of address space + descriptors. + @param[out] MinBus The lower range of bus number. + @param[out] MaxBus The upper range of bus number. + @param[out] IsEnd Meet end of the serial of descriptors. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciGetNextBusRange ( + IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, + OUT UINT16 *MinBus, + OUT UINT16 *MaxBus, + OUT BOOLEAN *IsEnd + ); + +/** + Explain the data in PCI configuration space. The part which is common for + PCI device and bridge is interpreted in this function. It calls other + functions to interpret data unique for device or bridge. + + @param[in] ConfigSpace Data in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. +**/ +VOID +PciExplainPci ( + IN PCI_CONFIG_SPACE *ConfigSpace, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ); + +/** + Explain the device specific part of data in PCI configuration space. + + @param[in] Device Data in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainDeviceData ( + IN PCI_DEVICE_HEADER_TYPE_REGION *Device, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ); + +/** + Explain the bridge specific part of data in PCI configuration space. + + @param[in] Bridge Bridge specific data region in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBridgeData ( + IN PCI_BRIDGE_CONTROL_REGISTER *Bridge, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ); + +/** + Explain the Base Address Register(Bar) in PCI configuration space. + + @param[in] Bar Points to the Base Address Register intended to interpret. + @param[in] Command Points to the register Command. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + @param[in, out] Index The Index. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBar ( + IN UINT32 *Bar, + IN UINT16 *Command, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, + IN OUT UINTN *Index + ); + +/** + Explain the cardbus specific part of data in PCI configuration space. + + @param[in] CardBus CardBus specific region of PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainCardBusData ( + IN PCI_CARDBUS_CONTROL_REGISTER *CardBus, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ); + +/** + Explain each meaningful bit of register Status. The definition of Status is + slightly different depending on the PCI header type. + + @param[in] Status Points to the content of register Status. + @param[in] MainStatus Indicates if this register is main status(not secondary + status). + @param[in] HeaderType Header type of this PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainStatus ( + IN UINT16 *Status, + IN BOOLEAN MainStatus, + IN PCI_HEADER_TYPE HeaderType + ); + +/** + Explain each meaningful bit of register Command. + + @param[in] Command Points to the content of register Command. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainCommand ( + IN UINT16 *Command + ); + +/** + Explain each meaningful bit of register Bridge Control. + + @param[in] BridgeControl Points to the content of register Bridge Control. + @param[in] HeaderType The headertype. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBridgeControl ( + IN UINT16 *BridgeControl, + IN PCI_HEADER_TYPE HeaderType + ); + +/** + Locate capability register block per capability ID. + + @param[in] ConfigSpace Data in PCI configuration space. + @param[in] CapabilityId The capability ID. + + @return The offset of the register block per capability ID. +**/ +UINT8 +LocatePciCapability ( + IN PCI_CONFIG_SPACE *ConfigSpace, + IN UINT8 CapabilityId + ); + +/** + Display Pcie device structure. + + @param[in] PciExpressCap PCI Express capability buffer. + @param[in] ExtendedConfigSpace PCI Express extended configuration space. + @param[in] ExtendedConfigSize PCI Express extended configuration size. + @param[in] ExtendedCapability PCI Express extended capability ID to explain. +**/ +VOID +PciExplainPciExpress ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap, + IN UINT8 *ExtendedConfigSpace, + IN UINTN ExtendedConfigSize, + IN CONST UINT16 ExtendedCapability + ); + +/** + Print out information of the capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieCapReg ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device link information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device link control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device link status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device slot information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device slot control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device slot status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device root information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device root capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +/** + Print out information of the device root status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ); + +typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCI_CAPABILITY_PCIEXP *PciExpressCap); + +typedef enum { + FieldWidthUINT8, + FieldWidthUINT16, + FieldWidthUINT32 +} PCIE_CAPREG_FIELD_WIDTH; + +typedef enum { + PcieExplainTypeCommon, + PcieExplainTypeDevice, + PcieExplainTypeLink, + PcieExplainTypeSlot, + PcieExplainTypeRoot, + PcieExplainTypeMax +} PCIE_EXPLAIN_TYPE; + +typedef struct +{ + UINT16 Token; + UINTN Offset; + PCIE_CAPREG_FIELD_WIDTH Width; + PCIE_EXPLAIN_FUNCTION Func; + PCIE_EXPLAIN_TYPE Type; +} PCIE_EXPLAIN_STRUCT; + +PCIE_EXPLAIN_STRUCT PcieExplainList[] = { + { + STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID), + 0x00, + FieldWidthUINT8, + NULL, + PcieExplainTypeCommon + }, + { + STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR), + 0x01, + FieldWidthUINT8, + NULL, + PcieExplainTypeCommon + }, + { + STRING_TOKEN (STR_PCIEX_CAP_REGISTER), + 0x02, + FieldWidthUINT16, + ExplainPcieCapReg, + PcieExplainTypeCommon + }, + { + STRING_TOKEN (STR_PCIEX_DEVICE_CAP), + 0x04, + FieldWidthUINT32, + ExplainPcieDeviceCap, + PcieExplainTypeDevice + }, + { + STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL), + 0x08, + FieldWidthUINT16, + ExplainPcieDeviceControl, + PcieExplainTypeDevice + }, + { + STRING_TOKEN (STR_PCIEX_DEVICE_STATUS), + 0x0a, + FieldWidthUINT16, + ExplainPcieDeviceStatus, + PcieExplainTypeDevice + }, + { + STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES), + 0x0c, + FieldWidthUINT32, + ExplainPcieLinkCap, + PcieExplainTypeLink + }, + { + STRING_TOKEN (STR_PCIEX_LINK_CONTROL), + 0x10, + FieldWidthUINT16, + ExplainPcieLinkControl, + PcieExplainTypeLink + }, + { + STRING_TOKEN (STR_PCIEX_LINK_STATUS), + 0x12, + FieldWidthUINT16, + ExplainPcieLinkStatus, + PcieExplainTypeLink + }, + { + STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES), + 0x14, + FieldWidthUINT32, + ExplainPcieSlotCap, + PcieExplainTypeSlot + }, + { + STRING_TOKEN (STR_PCIEX_SLOT_CONTROL), + 0x18, + FieldWidthUINT16, + ExplainPcieSlotControl, + PcieExplainTypeSlot + }, + { + STRING_TOKEN (STR_PCIEX_SLOT_STATUS), + 0x1a, + FieldWidthUINT16, + ExplainPcieSlotStatus, + PcieExplainTypeSlot + }, + { + STRING_TOKEN (STR_PCIEX_ROOT_CONTROL), + 0x1c, + FieldWidthUINT16, + ExplainPcieRootControl, + PcieExplainTypeRoot + }, + { + STRING_TOKEN (STR_PCIEX_RSVDP), + 0x1e, + FieldWidthUINT16, + ExplainPcieRootCap, + PcieExplainTypeRoot + }, + { + STRING_TOKEN (STR_PCIEX_ROOT_STATUS), + 0x20, + FieldWidthUINT32, + ExplainPcieRootStatus, + PcieExplainTypeRoot + }, + { + 0, + 0, + (PCIE_CAPREG_FIELD_WIDTH)0, + NULL, + PcieExplainTypeMax + } +}; + +// +// Global Variables +// +PCI_CONFIG_SPACE *mConfigSpace = NULL; +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-s", TypeValue}, + {L"-i", TypeFlag}, + {L"-ec", TypeValue}, + {NULL, TypeMax} + }; + +CHAR16 *DevicePortTypeTable[] = { + L"PCI Express Endpoint", + L"Legacy PCI Express Endpoint", + L"Unknown Type", + L"Unknonw Type", + L"Root Port of PCI Express Root Complex", + L"Upstream Port of PCI Express Switch", + L"Downstream Port of PCI Express Switch", + L"PCI Express to PCI/PCI-X Bridge", + L"PCI/PCI-X to PCI Express Bridge", + L"Root Complex Integrated Endpoint", + L"Root Complex Event Collector" +}; + +CHAR16 *L0sLatencyStrTable[] = { + L"Less than 64ns", + L"64ns to less than 128ns", + L"128ns to less than 256ns", + L"256ns to less than 512ns", + L"512ns to less than 1us", + L"1us to less than 2us", + L"2us-4us", + L"More than 4us" +}; + +CHAR16 *L1LatencyStrTable[] = { + L"Less than 1us", + L"1us to less than 2us", + L"2us to less than 4us", + L"4us to less than 8us", + L"8us to less than 16us", + L"16us to less than 32us", + L"32us-64us", + L"More than 64us" +}; + +CHAR16 *ASPMCtrlStrTable[] = { + L"Disabled", + L"L0s Entry Enabled", + L"L1 Entry Enabled", + L"L0s and L1 Entry Enabled" +}; + +CHAR16 *SlotPwrLmtScaleTable[] = { + L"1.0x", + L"0.1x", + L"0.01x", + L"0.001x" +}; + +CHAR16 *IndicatorTable[] = { + L"Reserved", + L"On", + L"Blink", + L"Off" +}; + + +/** + Function for 'pci' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunPci ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT16 Segment; + UINT16 Bus; + UINT16 Device; + UINT16 Func; + UINT64 Address; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev; + EFI_STATUS Status; + PCI_DEVICE_INDEPENDENT_REGION PciHeader; + PCI_CONFIG_SPACE ConfigSpace; + UINTN ScreenCount; + UINTN TempColumn; + UINTN ScreenSize; + BOOLEAN ExplainData; + UINTN Index; + UINTN SizeOfHeader; + BOOLEAN PrintTitle; + UINTN HandleBufSize; + EFI_HANDLE *HandleBuf; + UINTN HandleCount; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + UINT16 MinBus; + UINT16 MaxBus; + BOOLEAN IsEnd; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Temp; + UINT64 RetVal; + UINT16 ExtendedCapability; + UINT8 PcieCapabilityPtr; + UINT8 *ExtendedConfigSpace; + UINTN ExtendedConfigSize; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + Address = 0; + IoDev = NULL; + HandleBuf = NULL; + Package = NULL; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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), gShellDebug1HiiHandle, L"pci", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + + if (ShellCommandLineGetCount(Package) == 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if (ShellCommandLineGetCount(Package) > 4) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + if (ShellCommandLineGetFlag(Package, L"-ec") && ShellCommandLineGetValue(Package, L"-ec") == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"pci", L"-ec"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"pci", L"-s"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + // + // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and + // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough + // space for handles and call it again. + // + HandleBufSize = sizeof (EFI_HANDLE); + HandleBuf = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize); + if (HandleBuf == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Done; + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleBufSize, + HandleBuf + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf); + if (HandleBuf == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Done; + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleBufSize, + HandleBuf + ); + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + + HandleCount = HandleBufSize / sizeof (EFI_HANDLE); + // + // Argument Count == 1(no other argument): enumerate all pci functions + // + if (ShellCommandLineGetCount(Package) == 1) { + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &TempColumn, + &ScreenSize + ); + + ScreenCount = 0; + ScreenSize -= 4; + if ((ScreenSize & 1) == 1) { + ScreenSize -= 1; + } + + PrintTitle = TRUE; + + // + // For each handle, which decides a segment and a bus number range, + // enumerate all devices on it. + // + for (Index = 0; Index < HandleCount; Index++) { + Status = PciGetProtocolAndResource ( + HandleBuf[Index], + &IoDev, + &Descriptors + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + // + // No document say it's impossible for a RootBridgeIo protocol handle + // to have more than one address space descriptors, so find out every + // bus range and for each of them do device enumeration. + // + while (TRUE) { + Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd); + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + + if (IsEnd) { + break; + } + + for (Bus = MinBus; Bus <= MaxBus; Bus++) { + // + // For each devices, enumerate all functions it contains + // + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + // + // For each function, read its configuration space and print summary + // + for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { + if (ShellGetExecutionBreakFlag ()) { + ShellStatus = SHELL_ABORTED; + goto Done; + } + Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); + IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint16, + Address, + 1, + &PciHeader.VendorId + ); + + // + // If VendorId = 0xffff, there does not exist a device at this + // location. For each device, if there is any function on it, + // there must be 1 function at Function 0. So if Func = 0, there + // will be no more functions in the same device, so we can break + // loop to deal with the next device. + // + if (PciHeader.VendorId == 0xffff && Func == 0) { + break; + } + + if (PciHeader.VendorId != 0xffff) { + + if (PrintTitle) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle); + PrintTitle = FALSE; + } + + IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint32, + Address, + sizeof (PciHeader) / sizeof (UINT32), + &PciHeader + ); + + ShellPrintHiiEx( + -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle, + IoDev->SegmentNumber, + Bus, + Device, + Func + ); + + PciPrintClassCode (PciHeader.ClassCode, FALSE); + ShellPrintHiiEx( + -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle, + PciHeader.VendorId, + PciHeader.DeviceId, + PciHeader.ClassCode[0] + ); + + ScreenCount += 2; + if (ScreenCount >= ScreenSize && ScreenSize != 0) { + // + // If ScreenSize == 0 we have the console redirected so don't + // block updates + // + ScreenCount = 0; + } + // + // If this is not a multi-function device, we can leave the loop + // to deal with the next device. + // + if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) { + break; + } + } + } + } + } + // + // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED, + // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all + // devices on all bus, we can leave loop. + // + if (Descriptors == NULL) { + break; + } + } + } + + Status = EFI_SUCCESS; + goto Done; + } + + ExplainData = FALSE; + Segment = 0; + Bus = 0; + Device = 0; + Func = 0; + ExtendedCapability = 0xFFFF; + if (ShellCommandLineGetFlag(Package, L"-i")) { + ExplainData = TRUE; + } + + Temp = ShellCommandLineGetValue(Package, L"-s"); + if (Temp != NULL) { + // + // Input converted to hexadecimal number. + // + if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { + Segment = (UINT16) RetVal; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + + // + // The first Argument(except "-i") is assumed to be Bus number, second + // to be Device number, and third to be Func number. + // + Temp = ShellCommandLineGetRawValue(Package, 1); + if (Temp != NULL) { + // + // Input converted to hexadecimal number. + // + if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { + Bus = (UINT16) RetVal; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if (Bus > PCI_MAX_BUS) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + Temp = ShellCommandLineGetRawValue(Package, 2); + if (Temp != NULL) { + // + // Input converted to hexadecimal number. + // + if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { + Device = (UINT16) RetVal; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if (Device > PCI_MAX_DEVICE){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + + Temp = ShellCommandLineGetRawValue(Package, 3); + if (Temp != NULL) { + // + // Input converted to hexadecimal number. + // + if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { + Func = (UINT16) RetVal; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + if (Func > PCI_MAX_FUNC){ + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + + Temp = ShellCommandLineGetValue (Package, L"-ec"); + if (Temp != NULL) { + // + // Input converted to hexadecimal number. + // + if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) { + ExtendedCapability = (UINT16) RetVal; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle, L"pci", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + + // + // Find the protocol interface who's in charge of current segment, and its + // bus range covers the current bus + // + Status = PciFindProtocolInterface ( + HandleBuf, + HandleCount, + Segment, + Bus, + &IoDev + ); + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx( + -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle, L"pci", + Segment, + Bus + ); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + + Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); + Status = IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint8, + Address, + sizeof (ConfigSpace), + &ConfigSpace + ); + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, L"pci"); + ShellStatus = SHELL_ACCESS_DENIED; + goto Done; + } + + mConfigSpace = &ConfigSpace; + ShellPrintHiiEx( + -1, + -1, + NULL, + STRING_TOKEN (STR_PCI_INFO), + gShellDebug1HiiHandle, + Segment, + Bus, + Device, + Func, + Segment, + Bus, + Device, + Func + ); + + // + // Dump standard header of configuration space + // + SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon); + + DumpHex (2, 0, SizeOfHeader, &ConfigSpace); + ShellPrintEx(-1,-1, L"\r\n"); + + // + // Dump device dependent Part of configuration space + // + DumpHex ( + 2, + SizeOfHeader, + sizeof (ConfigSpace) - SizeOfHeader, + ConfigSpace.Data + ); + + ExtendedConfigSpace = NULL; + ExtendedConfigSize = 0; + PcieCapabilityPtr = LocatePciCapability (&ConfigSpace, EFI_PCI_CAPABILITY_ID_PCIEXP); + if (PcieCapabilityPtr != 0) { + ExtendedConfigSize = 0x1000 - EFI_PCIE_CAPABILITY_BASE_OFFSET; + ExtendedConfigSpace = AllocatePool (ExtendedConfigSize); + if (ExtendedConfigSpace != NULL) { + Status = IoDev->Pci.Read ( + IoDev, + EfiPciWidthUint32, + EFI_PCI_ADDRESS (Bus, Device, Func, EFI_PCIE_CAPABILITY_BASE_OFFSET), + ExtendedConfigSize / sizeof (UINT32), + ExtendedConfigSpace + ); + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (ExtendedConfigSpace); + } + } + } + + if ((ExtendedConfigSpace != NULL) && !ShellGetExecutionBreakFlag ()) { + // + // Print the PciEx extend space in raw bytes ( 0xFF-0xFFF) + // + ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n"); + + DumpHex ( + 2, + EFI_PCIE_CAPABILITY_BASE_OFFSET, + ExtendedConfigSize, + ExtendedConfigSpace + ); + } + + // + // If "-i" appears in command line, interpret data in configuration space + // + if (ExplainData) { + PciExplainPci (&ConfigSpace, Address, IoDev); + if ((ExtendedConfigSpace != NULL) && !ShellGetExecutionBreakFlag ()) { + PciExplainPciExpress ( + (PCI_CAPABILITY_PCIEXP *) ((UINT8 *) &ConfigSpace + PcieCapabilityPtr), + ExtendedConfigSpace, + ExtendedConfigSize, + ExtendedCapability + ); + } + } + } +Done: + if (HandleBuf != NULL) { + FreePool (HandleBuf); + } + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + mConfigSpace = NULL; + return ShellStatus; +} + +/** + This function finds out the protocol which is in charge of the given + segment, and its bus range covers the current bus number. It lookes + each instances of RootBridgeIoProtocol handle, until the one meets the + criteria is found. + + @param[in] HandleBuf Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. + @param[in] HandleCount Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles. + @param[in] Segment Segment number of device we are dealing with. + @param[in] Bus Bus number of device we are dealing with. + @param[out] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +PciFindProtocolInterface ( + IN EFI_HANDLE *HandleBuf, + IN UINTN HandleCount, + IN UINT16 Segment, + IN UINT16 Bus, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + UINT16 MinBus; + UINT16 MaxBus; + BOOLEAN IsEnd; + + // + // Go through all handles, until the one meets the criteria is found + // + for (Index = 0; Index < HandleCount; Index++) { + Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors); + if (EFI_ERROR (Status)) { + return Status; + } + // + // When Descriptors == NULL, the Configuration() is not implemented, + // so we only check the Segment number + // + if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) { + return EFI_SUCCESS; + } + + if ((*IoDev)->SegmentNumber != Segment) { + continue; + } + + while (TRUE) { + Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd); + if (EFI_ERROR (Status)) { + return Status; + } + + if (IsEnd) { + break; + } + + if (MinBus <= Bus && MaxBus >= Bus) { + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} + +/** + This function gets the protocol interface from the given handle, and + obtains its address space descriptors. + + @param[in] Handle The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle. + @param[out] IoDev Handle used to access configuration space of PCI device. + @param[out] Descriptors Points to the address space descriptors. + + @retval EFI_SUCCESS The command completed successfully +**/ +EFI_STATUS +PciGetProtocolAndResource ( + IN EFI_HANDLE Handle, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, + OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors + ) +{ + EFI_STATUS Status; + + // + // Get inferface from protocol + // + Status = gBS->HandleProtocol ( + Handle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID**)IoDev + ); + + if (EFI_ERROR (Status)) { + return Status; + } + // + // Call Configuration() to get address space descriptors + // + Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors); + if (Status == EFI_UNSUPPORTED) { + *Descriptors = NULL; + return EFI_SUCCESS; + + } else { + return Status; + } +} + +/** + This function get the next bus range of given address space descriptors. + It also moves the pointer backward a node, to get prepared to be called + again. + + @param[in, out] Descriptors Points to current position of a serial of address space + descriptors. + @param[out] MinBus The lower range of bus number. + @param[out] MaxBus The upper range of bus number. + @param[out] IsEnd Meet end of the serial of descriptors. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciGetNextBusRange ( + IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, + OUT UINT16 *MinBus, + OUT UINT16 *MaxBus, + OUT BOOLEAN *IsEnd + ) +{ + *IsEnd = FALSE; + + // + // When *Descriptors is NULL, Configuration() is not implemented, so assume + // range is 0~PCI_MAX_BUS + // + if ((*Descriptors) == NULL) { + *MinBus = 0; + *MaxBus = PCI_MAX_BUS; + return EFI_SUCCESS; + } + // + // *Descriptors points to one or more address space descriptors, which + // ends with a end tagged descriptor. Examine each of the descriptors, + // if a bus typed one is found and its bus range covers bus, this handle + // is the handle we are looking for. + // + + while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { + if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { + *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; + *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; + (*Descriptors)++; + return (EFI_SUCCESS); + } + + (*Descriptors)++; + } + + if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) { + *IsEnd = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Explain the data in PCI configuration space. The part which is common for + PCI device and bridge is interpreted in this function. It calls other + functions to interpret data unique for device or bridge. + + @param[in] ConfigSpace Data in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. +**/ +VOID +PciExplainPci ( + IN PCI_CONFIG_SPACE *ConfigSpace, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ) +{ + PCI_DEVICE_INDEPENDENT_REGION *Common; + PCI_HEADER_TYPE HeaderType; + + Common = &(ConfigSpace->Common); + + ShellPrintEx (-1, -1, L"\r\n"); + + // + // Print Vendor Id and Device Id + // + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle, + INDEX_OF (&(Common->VendorId)), + Common->VendorId, + INDEX_OF (&(Common->DeviceId)), + Common->DeviceId + ); + + // + // Print register Command + // + PciExplainCommand (&(Common->Command)); + + // + // Print register Status + // + PciExplainStatus (&(Common->Status), TRUE, PciUndefined); + + // + // Print register Revision ID + // + ShellPrintEx(-1, -1, L"\r\n"); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle, + INDEX_OF (&(Common->RevisionID)), + Common->RevisionID + ); + + // + // Print register BIST + // + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->BIST))); + if ((Common->BIST & BIT7) != 0) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->BIST); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle); + } + // + // Print register Cache Line Size + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE), + gShellDebug1HiiHandle, + INDEX_OF (&(Common->CacheLineSize)), + Common->CacheLineSize + ); + + // + // Print register Latency Timer + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_LATENCY_TIMER), + gShellDebug1HiiHandle, + INDEX_OF (&(Common->LatencyTimer)), + Common->LatencyTimer + ); + + // + // Print register Header Type + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_HEADER_TYPE), + gShellDebug1HiiHandle, + INDEX_OF (&(Common->HeaderType)), + Common->HeaderType + ); + + if ((Common->HeaderType & BIT7) != 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle); + } + + HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f); + switch (HeaderType) { + case PciDevice: + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle); + break; + + case PciP2pBridge: + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle); + break; + + case PciCardBusBridge: + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle); + HeaderType = PciUndefined; + } + + // + // Print register Class Code + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle); + PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE); + ShellPrintEx (-1, -1, L"\r\n"); +} + +/** + Explain the device specific part of data in PCI configuration space. + + @param[in] Device Data in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainDeviceData ( + IN PCI_DEVICE_HEADER_TYPE_REGION *Device, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ) +{ + UINTN Index; + BOOLEAN BarExist; + EFI_STATUS Status; + UINTN BarCount; + + // + // Print Base Address Registers(Bar). When Bar = 0, this Bar does not + // exist. If these no Bar for this function, print "none", otherwise + // list detail information about this Bar. + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar)); + + BarExist = FALSE; + BarCount = sizeof (Device->Bar) / sizeof (Device->Bar[0]); + for (Index = 0; Index < BarCount; Index++) { + if (Device->Bar[Index] == 0) { + continue; + } + + if (!BarExist) { + BarExist = TRUE; + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle); + ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------"); + } + + Status = PciExplainBar ( + &(Device->Bar[Index]), + &(mConfigSpace->Common.Command), + Address, + IoDev, + &Index + ); + + if (EFI_ERROR (Status)) { + break; + } + } + + if (!BarExist) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle); + + } else { + ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------"); + } + + // + // Print register Expansion ROM Base Address + // + if ((Device->ExpansionRomBar & BIT0) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ExpansionRomBar))); + + } else { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->ExpansionRomBar)), + Device->ExpansionRomBar + ); + } + // + // Print register Cardbus CIS ptr + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CARDBUS_CIS), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->CISPtr)), + Device->CISPtr + ); + + // + // Print register Sub-vendor ID and subsystem ID + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->SubsystemVendorID)), + Device->SubsystemVendorID + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->SubsystemID)), + Device->SubsystemID + ); + + // + // Print register Capabilities Ptr + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->CapabilityPtr)), + Device->CapabilityPtr + ); + + // + // Print register Interrupt Line and interrupt pin + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_INTERRUPT_LINE), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->InterruptLine)), + Device->InterruptLine + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_INTERRUPT_PIN), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->InterruptPin)), + Device->InterruptPin + ); + + // + // Print register Min_Gnt and Max_Lat + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MIN_GNT), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->MinGnt)), + Device->MinGnt + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MAX_LAT), + gShellDebug1HiiHandle, + INDEX_OF (&(Device->MaxLat)), + Device->MaxLat + ); + + return EFI_SUCCESS; +} + +/** + Explain the bridge specific part of data in PCI configuration space. + + @param[in] Bridge Bridge specific data region in PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBridgeData ( + IN PCI_BRIDGE_CONTROL_REGISTER *Bridge, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ) +{ + UINTN Index; + BOOLEAN BarExist; + UINTN BarCount; + UINT32 IoAddress32; + EFI_STATUS Status; + + // + // Print Base Address Registers. When Bar = 0, this Bar does not + // exist. If these no Bar for this function, print "none", otherwise + // list detail information about this Bar. + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar))); + + BarExist = FALSE; + BarCount = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]); + + for (Index = 0; Index < BarCount; Index++) { + if (Bridge->Bar[Index] == 0) { + continue; + } + + if (!BarExist) { + BarExist = TRUE; + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle); + ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------"); + } + + Status = PciExplainBar ( + &(Bridge->Bar[Index]), + &(mConfigSpace->Common.Command), + Address, + IoDev, + &Index + ); + + if (EFI_ERROR (Status)) { + break; + } + } + + if (!BarExist) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle); + } else { + ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------"); + } + + // + // Expansion register ROM Base Address + // + if ((Bridge->ExpansionRomBAR & BIT0) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ExpansionRomBAR))); + + } else { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->ExpansionRomBAR)), + Bridge->ExpansionRomBAR + ); + } + // + // Print Bus Numbers(Primary, Secondary, and Subordinate + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_BUS_NUMBERS), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->PrimaryBus)), + INDEX_OF (&(Bridge->SecondaryBus)), + INDEX_OF (&(Bridge->SubordinateBus)) + ); + + ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n"); + + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus); + + // + // Print register Secondary Latency Timer + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SECONDARY_TIMER), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->SecondaryLatencyTimer)), + Bridge->SecondaryLatencyTimer + ); + + // + // Print register Secondary Status + // + PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge); + + // + // Print I/O and memory ranges this bridge forwards. There are 3 resource + // types: I/O, memory, and pre-fetchable memory. For each resource type, + // base and limit address are listed. + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle); + ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n"); + + // + // IO Base & Limit + // + IoAddress32 = (Bridge->IoBaseUpper16 << 16 | Bridge->IoBase << 8); + IoAddress32 &= 0xfffff000; + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_TWO_VARS), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->IoBase)), + IoAddress32 + ); + + IoAddress32 = (Bridge->IoLimitUpper16 << 16 | Bridge->IoLimit << 8); + IoAddress32 |= 0x00000fff; + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32); + + // + // Memory Base & Limit + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MEMORY), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->MemoryBase)), + (Bridge->MemoryBase << 16) & 0xfff00000 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_ONE_VAR), + gShellDebug1HiiHandle, + (Bridge->MemoryLimit << 16) | 0x000fffff + ); + + // + // Pre-fetch-able Memory Base & Limit + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_PREFETCHABLE), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->PrefetchableMemoryBase)), + Bridge->PrefetchableBaseUpper32, + (Bridge->PrefetchableMemoryBase << 16) & 0xfff00000 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_TWO_VARS_2), + gShellDebug1HiiHandle, + Bridge->PrefetchableLimitUpper32, + (Bridge->PrefetchableMemoryLimit << 16) | 0x000fffff + ); + + // + // Print register Capabilities Pointer + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->CapabilityPtr)), + Bridge->CapabilityPtr + ); + + // + // Print register Bridge Control + // + PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge); + + // + // Print register Interrupt Line & PIN + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->InterruptLine)), + Bridge->InterruptLine + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_INTERRUPT_PIN), + gShellDebug1HiiHandle, + INDEX_OF (&(Bridge->InterruptPin)), + Bridge->InterruptPin + ); + + return EFI_SUCCESS; +} + +/** + Explain the Base Address Register(Bar) in PCI configuration space. + + @param[in] Bar Points to the Base Address Register intended to interpret. + @param[in] Command Points to the register Command. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + @param[in, out] Index The Index. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBar ( + IN UINT32 *Bar, + IN UINT16 *Command, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev, + IN OUT UINTN *Index + ) +{ + UINT16 OldCommand; + UINT16 NewCommand; + UINT64 Bar64; + UINT32 OldBar32; + UINT32 NewBar32; + UINT64 OldBar64; + UINT64 NewBar64; + BOOLEAN IsMem; + BOOLEAN IsBar32; + UINT64 RegAddress; + + IsBar32 = TRUE; + Bar64 = 0; + NewBar32 = 0; + NewBar64 = 0; + + // + // According the bar type, list detail about this bar, for example: 32 or + // 64 bits; pre-fetchable or not. + // + if ((*Bar & BIT0) == 0) { + // + // This bar is of memory type + // + IsMem = TRUE; + + if ((*Bar & BIT1) == 0 && (*Bar & BIT2) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle); + + } else if ((*Bar & BIT1) == 0 && (*Bar & BIT2) != 0) { + Bar64 = 0x0; + CopyMem (&Bar64, Bar, sizeof (UINT64)); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32)); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL)); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle); + IsBar32 = FALSE; + *Index += 1; + + } else { + // + // Reserved + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle); + } + + if ((*Bar & BIT3) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle); + } + + } else { + // + // This bar is of io type + // + IsMem = FALSE; + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc); + ShellPrintEx (-1, -1, L"I/O "); + } + + // + // Get BAR length(or the amount of resource this bar demands for). To get + // Bar length, first we should temporarily disable I/O and memory access + // of this function(by set bits in the register Command), then write all + // "1"s to this bar. The bar value read back is the amount of resource + // this bar demands for. + // + // + // Disable io & mem access + // + OldCommand = *Command; + NewCommand = (UINT16) (OldCommand & 0xfffc); + RegAddress = Address | INDEX_OF (Command); + IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand); + + RegAddress = Address | INDEX_OF (Bar); + + // + // Read after write the BAR to get the size + // + if (IsBar32) { + OldBar32 = *Bar; + NewBar32 = 0xffffffff; + + IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32); + IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32); + IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32); + + if (IsMem) { + NewBar32 = NewBar32 & 0xfffffff0; + NewBar32 = (~NewBar32) + 1; + + } else { + NewBar32 = NewBar32 & 0xfffffffc; + NewBar32 = (~NewBar32) + 1; + NewBar32 = NewBar32 & 0x0000ffff; + } + } else { + + OldBar64 = 0x0; + CopyMem (&OldBar64, Bar, sizeof (UINT64)); + NewBar64 = 0xffffffffffffffffULL; + + IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64); + IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64); + IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64); + + if (IsMem) { + NewBar64 = NewBar64 & 0xfffffffffffffff0ULL; + NewBar64 = (~NewBar64) + 1; + + } else { + NewBar64 = NewBar64 & 0xfffffffffffffffcULL; + NewBar64 = (~NewBar64) + 1; + NewBar64 = NewBar64 & 0x000000000000ffff; + } + } + // + // Enable io & mem access + // + RegAddress = Address | INDEX_OF (Command); + IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand); + + if (IsMem) { + if (IsBar32) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32)); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64); + ShellPrintEx (-1, -1, L" "); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_RSHIFT), + gShellDebug1HiiHandle, + (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32) + ); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1)); + + } + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1); + } + + return EFI_SUCCESS; +} + +/** + Explain the cardbus specific part of data in PCI configuration space. + + @param[in] CardBus CardBus specific region of PCI configuration space. + @param[in] Address Address used to access configuration space of this PCI device. + @param[in] IoDev Handle used to access configuration space of PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainCardBusData ( + IN PCI_CARDBUS_CONTROL_REGISTER *CardBus, + IN UINT64 Address, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev + ) +{ + BOOLEAN Io32Bit; + PCI_CARDBUS_DATA *CardBusData; + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->CardBusSocketReg)), + CardBus->CardBusSocketReg + ); + + // + // Print Secondary Status + // + PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge); + + // + // Print Bus Numbers(Primary bus number, CardBus bus number, and + // Subordinate bus number + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->PciBusNumber)), + INDEX_OF (&(CardBus->CardBusBusNumber)), + INDEX_OF (&(CardBus->SubordinateBusNumber)) + ); + + ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n"); + + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber); + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber); + + // + // Print CardBus Latency Timer + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->CardBusLatencyTimer)), + CardBus->CardBusLatencyTimer + ); + + // + // Print Memory/Io ranges this cardbus bridge forwards + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle); + ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n"); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MEM_3), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->MemoryBase0)), + CardBus->BridgeControl & BIT8 ? L" Prefetchable" : L"Non-Prefetchable", + CardBus->MemoryBase0 & 0xfffff000, + CardBus->MemoryLimit0 | 0x00000fff + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MEM_3), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->MemoryBase1)), + CardBus->BridgeControl & BIT9 ? L" Prefetchable" : L"Non-Prefetchable", + CardBus->MemoryBase1 & 0xfffff000, + CardBus->MemoryLimit1 | 0x00000fff + ); + + Io32Bit = (BOOLEAN) (CardBus->IoBase0 & BIT0); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_IO_2), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->IoBase0)), + Io32Bit ? L" 32 bit" : L" 16 bit", + CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc), + (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003 + ); + + Io32Bit = (BOOLEAN) (CardBus->IoBase1 & BIT0); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_IO_2), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->IoBase1)), + Io32Bit ? L" 32 bit" : L" 16 bit", + CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc), + (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003 + ); + + // + // Print register Interrupt Line & PIN + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBus->InterruptLine)), + CardBus->InterruptLine, + INDEX_OF (&(CardBus->InterruptPin)), + CardBus->InterruptPin + ); + + // + // Print register Bridge Control + // + PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge); + + // + // Print some registers in data region of PCI configuration space for cardbus + // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base + // Address. + // + CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_CONTROL_REGISTER)); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBusData->SubVendorId)), + CardBusData->SubVendorId, + INDEX_OF (&(CardBusData->SubSystemId)), + CardBusData->SubSystemId + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_OPTIONAL), + gShellDebug1HiiHandle, + INDEX_OF (&(CardBusData->LegacyBase)), + CardBusData->LegacyBase + ); + + return EFI_SUCCESS; +} + +/** + Explain each meaningful bit of register Status. The definition of Status is + slightly different depending on the PCI header type. + + @param[in] Status Points to the content of register Status. + @param[in] MainStatus Indicates if this register is main status(not secondary + status). + @param[in] HeaderType Header type of this PCI device. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainStatus ( + IN UINT16 *Status, + IN BOOLEAN MainStatus, + IN PCI_HEADER_TYPE HeaderType + ) +{ + if (MainStatus) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status); + } + + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & BIT4) != 0); + + // + // Bit 5 is meaningless for CardBus Bridge + // + if (HeaderType == PciCardBusBridge) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & BIT5) != 0); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & BIT5) != 0); + } + + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & BIT7) != 0); + + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & BIT8) != 0); + // + // Bit 9 and bit 10 together decides the DEVSEL timing + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle); + if ((*Status & BIT9) == 0 && (*Status & BIT10) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle); + + } else if ((*Status & BIT9) != 0 && (*Status & BIT10) == 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle); + + } else if ((*Status & BIT9) == 0 && (*Status & BIT10) != 0) { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle); + + } else { + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle); + } + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SIGNALED_TARGET), + gShellDebug1HiiHandle, + (*Status & BIT11) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_RECEIVED_TARGET), + gShellDebug1HiiHandle, + (*Status & BIT12) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_RECEIVED_MASTER), + gShellDebug1HiiHandle, + (*Status & BIT13) != 0 + ); + + if (MainStatus) { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SIGNALED_ERROR), + gShellDebug1HiiHandle, + (*Status & BIT14) != 0 + ); + + } else { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_RECEIVED_ERROR), + gShellDebug1HiiHandle, + (*Status & BIT14) != 0 + ); + } + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_DETECTED_ERROR), + gShellDebug1HiiHandle, + (*Status & BIT15) != 0 + ); + + return EFI_SUCCESS; +} + +/** + Explain each meaningful bit of register Command. + + @param[in] Command Points to the content of register Command. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainCommand ( + IN UINT16 *Command + ) +{ + // + // Print the binary value of register Command + // + ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command); + + // + // Explain register Command bit by bit + // + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED), + gShellDebug1HiiHandle, + (*Command & BIT0) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MEMORY_SPACE), + gShellDebug1HiiHandle, + (*Command & BIT1) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER), + gShellDebug1HiiHandle, + (*Command & BIT2) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE), + gShellDebug1HiiHandle, + (*Command & BIT3) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE), + gShellDebug1HiiHandle, + (*Command & BIT4) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING), + gShellDebug1HiiHandle, + (*Command & BIT5) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_ASSERT_PERR), + gShellDebug1HiiHandle, + (*Command & BIT6) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING), + gShellDebug1HiiHandle, + (*Command & BIT7) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SERR_DRIVER), + gShellDebug1HiiHandle, + (*Command & BIT8) != 0 + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_FAST_BACK_2), + gShellDebug1HiiHandle, + (*Command & BIT9) != 0 + ); + + return EFI_SUCCESS; +} + +/** + Explain each meaningful bit of register Bridge Control. + + @param[in] BridgeControl Points to the content of register Bridge Control. + @param[in] HeaderType The headertype. + + @retval EFI_SUCCESS The command completed successfully. +**/ +EFI_STATUS +PciExplainBridgeControl ( + IN UINT16 *BridgeControl, + IN PCI_HEADER_TYPE HeaderType + ) +{ + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL), + gShellDebug1HiiHandle, + INDEX_OF (BridgeControl), + *BridgeControl + ); + + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_PARITY_ERROR), + gShellDebug1HiiHandle, + (*BridgeControl & BIT0) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SERR_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT1) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_ISA_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT2) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_VGA_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT3) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_MASTER_ABORT), + gShellDebug1HiiHandle, + (*BridgeControl & BIT5) != 0 + ); + + // + // Register Bridge Control has some slight differences between P2P bridge + // and Cardbus bridge from bit 6 to bit 11. + // + if (HeaderType == PciP2pBridge) { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET), + gShellDebug1HiiHandle, + (*BridgeControl & BIT6) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_FAST_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT7) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER), + gShellDebug1HiiHandle, + (*BridgeControl & BIT8)!=0 ? L"2^10" : L"2^15" + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER), + gShellDebug1HiiHandle, + (*BridgeControl & BIT9)!=0 ? L"2^10" : L"2^15" + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS), + gShellDebug1HiiHandle, + (*BridgeControl & BIT10) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR), + gShellDebug1HiiHandle, + (*BridgeControl & BIT11) != 0 + ); + + } else { + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_CARDBUS_RESET), + gShellDebug1HiiHandle, + (*BridgeControl & BIT6) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_IREQ_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT7) != 0 + ); + ShellPrintHiiEx(-1, -1, NULL, + STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE), + gShellDebug1HiiHandle, + (*BridgeControl & BIT10) != 0 + ); + } + + return EFI_SUCCESS; +} + +/** + Locate capability register block per capability ID. + + @param[in] ConfigSpace Data in PCI configuration space. + @param[in] CapabilityId The capability ID. + + @return The offset of the register block per capability ID, + or 0 if the register block cannot be found. +**/ +UINT8 +LocatePciCapability ( + IN PCI_CONFIG_SPACE *ConfigSpace, + IN UINT8 CapabilityId + ) +{ + UINT8 CapabilityPtr; + EFI_PCI_CAPABILITY_HDR *CapabilityEntry; + + // + // To check the cpability of this device supports + // + if ((ConfigSpace->Common.Status & EFI_PCI_STATUS_CAPABILITY) == 0) { + return 0; + } + + switch ((PCI_HEADER_TYPE)(ConfigSpace->Common.HeaderType & 0x7f)) { + case PciDevice: + CapabilityPtr = ConfigSpace->NonCommon.Device.CapabilityPtr; + break; + case PciP2pBridge: + CapabilityPtr = ConfigSpace->NonCommon.Bridge.CapabilityPtr; + break; + case PciCardBusBridge: + CapabilityPtr = ConfigSpace->NonCommon.CardBus.Cap_Ptr; + break; + default: + return 0; + } + + while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) { + CapabilityEntry = (EFI_PCI_CAPABILITY_HDR *) ((UINT8 *) ConfigSpace + CapabilityPtr); + if (CapabilityEntry->CapabilityID == CapabilityId) { + return CapabilityPtr; + } + + // + // Certain PCI device may incorrectly have capability pointing to itself, + // break to avoid dead loop. + // + if (CapabilityPtr == CapabilityEntry->NextItemPtr) { + break; + } + + CapabilityPtr = CapabilityEntry->NextItemPtr; + } + + return 0; +} + +/** + Print out information of the capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieCapReg ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + CHAR16 *DevicePortType; + + ShellPrintEx (-1, -1, + L" Capability Version(3:0): %E0x%04x%N\r\n", + PciExpressCap->Capability.Bits.Version + ); + if (PciExpressCap->Capability.Bits.DevicePortType < ARRAY_SIZE (DevicePortTypeTable)) { + DevicePortType = DevicePortTypeTable[PciExpressCap->Capability.Bits.DevicePortType]; + } else { + DevicePortType = L"Unknown Type"; + } + ShellPrintEx (-1, -1, + L" Device/PortType(7:4): %E%s%N\r\n", + DevicePortType + ); + // + // 'Slot Implemented' is only valid for: + // a) Root Port of PCI Express Root Complex, or + // b) Downstream Port of PCI Express Switch + // + if (PciExpressCap->Capability.Bits.DevicePortType== PCIE_DEVICE_PORT_TYPE_ROOT_PORT || + PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) { + ShellPrintEx (-1, -1, + L" Slot Implemented(8): %E%d%N\r\n", + PciExpressCap->Capability.Bits.SlotImplemented + ); + } + ShellPrintEx (-1, -1, + L" Interrupt Message Number(13:9): %E0x%05x%N\r\n", + PciExpressCap->Capability.Bits.InterruptMessageNumber + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + UINT8 DevicePortType; + UINT8 L0sLatency; + UINT8 L1Latency; + + DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType; + ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): "); + if (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize < 6) { + ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceCapability.Bits.MaxPayloadSize + 7)); + } else { + ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); + } + ShellPrintEx (-1, -1, + L" Phantom Functions Supported(4:3): %E%d%N\r\n", + PciExpressCap->DeviceCapability.Bits.PhantomFunctions + ); + ShellPrintEx (-1, -1, + L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n", + PciExpressCap->DeviceCapability.Bits.ExtendedTagField ? 8 : 5 + ); + // + // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint + // + if (IS_PCIE_ENDPOINT (DevicePortType)) { + L0sLatency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL0sAcceptableLatency; + L1Latency = (UINT8)PciExpressCap->DeviceCapability.Bits.EndpointL1AcceptableLatency; + ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): "); + if (L0sLatency < 4) { + ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6)); + } else { + if (L0sLatency < 7) { + ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3)); + } else { + ShellPrintEx (-1, -1, L"%ENo limit%N\r\n"); + } + } + ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): "); + if (L1Latency < 7) { + ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1)); + } else { + ShellPrintEx (-1, -1, L"%ENo limit%N\r\n"); + } + } + ShellPrintEx (-1, -1, + L" Role-based Error Reporting(15): %E%d%N\r\n", + PciExpressCap->DeviceCapability.Bits.RoleBasedErrorReporting + ); + // + // Only valid for Upstream Port: + // a) Captured Slot Power Limit Value + // b) Captured Slot Power Scale + // + if (DevicePortType == PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) { + ShellPrintEx (-1, -1, + L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n", + PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitValue + ); + ShellPrintEx (-1, -1, + L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n", + SlotPwrLmtScaleTable[PciExpressCap->DeviceCapability.Bits.CapturedSlotPowerLimitScale] + ); + } + // + // Function Level Reset Capability is only valid for Endpoint + // + if (IS_PCIE_ENDPOINT (DevicePortType)) { + ShellPrintEx (-1, -1, + L" Function Level Reset Capability(28): %E%d%N\r\n", + PciExpressCap->DeviceCapability.Bits.FunctionLevelReset + ); + } + return EFI_SUCCESS; +} + +/** + Print out information of the device control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" Correctable Error Reporting Enable(0): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.CorrectableError + ); + ShellPrintEx (-1, -1, + L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.NonFatalError + ); + ShellPrintEx (-1, -1, + L" Fatal Error Reporting Enable(2): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.FatalError + ); + ShellPrintEx (-1, -1, + L" Unsupported Request Reporting Enable(3): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.UnsupportedRequest + ); + ShellPrintEx (-1, -1, + L" Enable Relaxed Ordering(4): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.RelaxedOrdering + ); + ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): "); + if (PciExpressCap->DeviceControl.Bits.MaxPayloadSize < 6) { + ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxPayloadSize + 7)); + } else { + ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); + } + ShellPrintEx (-1, -1, + L" Extended Tag Field Enable(8): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.ExtendedTagField + ); + ShellPrintEx (-1, -1, + L" Phantom Functions Enable(9): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.PhantomFunctions + ); + ShellPrintEx (-1, -1, + L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.AuxPower + ); + ShellPrintEx (-1, -1, + L" Enable No Snoop(11): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.NoSnoop + ); + ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): "); + if (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize < 6) { + ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PciExpressCap->DeviceControl.Bits.MaxReadRequestSize + 7)); + } else { + ShellPrintEx (-1, -1, L"%EUnknown%N\r\n"); + } + // + // Read operation is only valid for PCI Express to PCI/PCI-X Bridges + // + if (PciExpressCap->Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) { + ShellPrintEx (-1, -1, + L" Bridge Configuration Retry Enable(15): %E%d%N\r\n", + PciExpressCap->DeviceControl.Bits.BridgeConfigurationRetryOrFunctionLevelReset + ); + } + return EFI_SUCCESS; +} + +/** + Print out information of the device status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieDeviceStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" Correctable Error Detected(0): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.CorrectableError + ); + ShellPrintEx (-1, -1, + L" Non-Fatal Error Detected(1): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.NonFatalError + ); + ShellPrintEx (-1, -1, + L" Fatal Error Detected(2): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.FatalError + ); + ShellPrintEx (-1, -1, + L" Unsupported Request Detected(3): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.UnsupportedRequest + ); + ShellPrintEx (-1, -1, + L" AUX Power Detected(4): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.AuxPower + ); + ShellPrintEx (-1, -1, + L" Transactions Pending(5): %E%d%N\r\n", + PciExpressCap->DeviceStatus.Bits.TransactionsPending + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device link information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + CHAR16 *MaxLinkSpeed; + CHAR16 *AspmValue; + + switch (PciExpressCap->LinkCapability.Bits.MaxLinkSpeed) { + case 1: + MaxLinkSpeed = L"2.5 GT/s"; + break; + case 2: + MaxLinkSpeed = L"5.0 GT/s"; + break; + case 3: + MaxLinkSpeed = L"8.0 GT/s"; + break; + case 4: + MaxLinkSpeed = L"16.0 GT/s"; + break; + case 5: + MaxLinkSpeed = L"32.0 GT/s"; + break; + default: + MaxLinkSpeed = L"Reserved"; + break; + } + ShellPrintEx (-1, -1, + L" Maximum Link Speed(3:0): %E%s%N\r\n", + MaxLinkSpeed + ); + ShellPrintEx (-1, -1, + L" Maximum Link Width(9:4): %Ex%d%N\r\n", + PciExpressCap->LinkCapability.Bits.MaxLinkWidth + ); + switch (PciExpressCap->LinkCapability.Bits.Aspm) { + case 0: + AspmValue = L"Not"; + break; + case 1: + AspmValue = L"L0s"; + break; + case 2: + AspmValue = L"L1"; + break; + case 3: + AspmValue = L"L0s and L1"; + break; + default: + AspmValue = L"Reserved"; + break; + } + ShellPrintEx (-1, -1, + L" Active State Power Management Support(11:10): %E%s Supported%N\r\n", + AspmValue + ); + ShellPrintEx (-1, -1, + L" L0s Exit Latency(14:12): %E%s%N\r\n", + L0sLatencyStrTable[PciExpressCap->LinkCapability.Bits.L0sExitLatency] + ); + ShellPrintEx (-1, -1, + L" L1 Exit Latency(17:15): %E%s%N\r\n", + L1LatencyStrTable[PciExpressCap->LinkCapability.Bits.L1ExitLatency] + ); + ShellPrintEx (-1, -1, + L" Clock Power Management(18): %E%d%N\r\n", + PciExpressCap->LinkCapability.Bits.ClockPowerManagement + ); + ShellPrintEx (-1, -1, + L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n", + PciExpressCap->LinkCapability.Bits.SurpriseDownError + ); + ShellPrintEx (-1, -1, + L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n", + PciExpressCap->LinkCapability.Bits.DataLinkLayerLinkActive + ); + ShellPrintEx (-1, -1, + L" Link Bandwidth Notification Capability(21): %E%d%N\r\n", + PciExpressCap->LinkCapability.Bits.LinkBandwidthNotification + ); + ShellPrintEx (-1, -1, + L" Port Number(31:24): %E0x%02x%N\r\n", + PciExpressCap->LinkCapability.Bits.PortNumber + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device link control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + UINT8 DevicePortType; + + DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType; + ShellPrintEx (-1, -1, + L" Active State Power Management Control(1:0): %E%s%N\r\n", + ASPMCtrlStrTable[PciExpressCap->LinkControl.Bits.AspmControl] + ); + // + // RCB is not applicable to switches + // + if (!IS_PCIE_SWITCH(DevicePortType)) { + ShellPrintEx (-1, -1, + L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n", + 1 << (PciExpressCap->LinkControl.Bits.ReadCompletionBoundary + 6) + ); + } + // + // Link Disable is reserved on + // a) Endpoints + // b) PCI Express to PCI/PCI-X bridges + // c) Upstream Ports of Switches + // + if (!IS_PCIE_ENDPOINT (DevicePortType) && + DevicePortType != PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT && + DevicePortType != PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE) { + ShellPrintEx (-1, -1, + L" Link Disable(4): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.LinkDisable + ); + } + ShellPrintEx (-1, -1, + L" Common Clock Configuration(6): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.CommonClockConfiguration + ); + ShellPrintEx (-1, -1, + L" Extended Synch(7): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.ExtendedSynch + ); + ShellPrintEx (-1, -1, + L" Enable Clock Power Management(8): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.ClockPowerManagement + ); + ShellPrintEx (-1, -1, + L" Hardware Autonomous Width Disable(9): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.HardwareAutonomousWidthDisable + ); + ShellPrintEx (-1, -1, + L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.LinkBandwidthManagementInterrupt + ); + ShellPrintEx (-1, -1, + L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n", + PciExpressCap->LinkControl.Bits.LinkAutonomousBandwidthInterrupt + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device link status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieLinkStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + CHAR16 *CurLinkSpeed; + + switch (PciExpressCap->LinkStatus.Bits.CurrentLinkSpeed) { + case 1: + CurLinkSpeed = L"2.5 GT/s"; + break; + case 2: + CurLinkSpeed = L"5.0 GT/s"; + break; + case 3: + CurLinkSpeed = L"8.0 GT/s"; + break; + case 4: + CurLinkSpeed = L"16.0 GT/s"; + break; + case 5: + CurLinkSpeed = L"32.0 GT/s"; + break; + default: + CurLinkSpeed = L"Reserved"; + break; + } + ShellPrintEx (-1, -1, + L" Current Link Speed(3:0): %E%s%N\r\n", + CurLinkSpeed + ); + ShellPrintEx (-1, -1, + L" Negotiated Link Width(9:4): %Ex%d%N\r\n", + PciExpressCap->LinkStatus.Bits.NegotiatedLinkWidth + ); + ShellPrintEx (-1, -1, + L" Link Training(11): %E%d%N\r\n", + PciExpressCap->LinkStatus.Bits.LinkTraining + ); + ShellPrintEx (-1, -1, + L" Slot Clock Configuration(12): %E%d%N\r\n", + PciExpressCap->LinkStatus.Bits.SlotClockConfiguration + ); + ShellPrintEx (-1, -1, + L" Data Link Layer Link Active(13): %E%d%N\r\n", + PciExpressCap->LinkStatus.Bits.DataLinkLayerLinkActive + ); + ShellPrintEx (-1, -1, + L" Link Bandwidth Management Status(14): %E%d%N\r\n", + PciExpressCap->LinkStatus.Bits.LinkBandwidthManagement + ); + ShellPrintEx (-1, -1, + L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n", + PciExpressCap->LinkStatus.Bits.LinkAutonomousBandwidth + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device slot information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" Attention Button Present(0): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.AttentionButton + ); + ShellPrintEx (-1, -1, + L" Power Controller Present(1): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.PowerController + ); + ShellPrintEx (-1, -1, + L" MRL Sensor Present(2): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.MrlSensor + ); + ShellPrintEx (-1, -1, + L" Attention Indicator Present(3): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.AttentionIndicator + ); + ShellPrintEx (-1, -1, + L" Power Indicator Present(4): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.PowerIndicator + ); + ShellPrintEx (-1, -1, + L" Hot-Plug Surprise(5): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.HotPlugSurprise + ); + ShellPrintEx (-1, -1, + L" Hot-Plug Capable(6): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.HotPlugCapable + ); + ShellPrintEx (-1, -1, + L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n", + PciExpressCap->SlotCapability.Bits.SlotPowerLimitValue + ); + ShellPrintEx (-1, -1, + L" Slot Power Limit Scale(16:15): %E%s%N\r\n", + SlotPwrLmtScaleTable[PciExpressCap->SlotCapability.Bits.SlotPowerLimitScale] + ); + ShellPrintEx (-1, -1, + L" Electromechanical Interlock Present(17): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.ElectromechanicalInterlock + ); + ShellPrintEx (-1, -1, + L" No Command Completed Support(18): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.NoCommandCompleted + ); + ShellPrintEx (-1, -1, + L" Physical Slot Number(31:19): %E%d%N\r\n", + PciExpressCap->SlotCapability.Bits.PhysicalSlotNumber + ); + + return EFI_SUCCESS; +} + +/** + Print out information of the device slot control information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" Attention Button Pressed Enable(0): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.AttentionButtonPressed + ); + ShellPrintEx (-1, -1, + L" Power Fault Detected Enable(1): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.PowerFaultDetected + ); + ShellPrintEx (-1, -1, + L" MRL Sensor Changed Enable(2): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.MrlSensorChanged + ); + ShellPrintEx (-1, -1, + L" Presence Detect Changed Enable(3): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.PresenceDetectChanged + ); + ShellPrintEx (-1, -1, + L" Command Completed Interrupt Enable(4): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.CommandCompletedInterrupt + ); + ShellPrintEx (-1, -1, + L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.HotPlugInterrupt + ); + ShellPrintEx (-1, -1, + L" Attention Indicator Control(7:6): %E%s%N\r\n", + IndicatorTable[ + PciExpressCap->SlotControl.Bits.AttentionIndicator] + ); + ShellPrintEx (-1, -1, + L" Power Indicator Control(9:8): %E%s%N\r\n", + IndicatorTable[PciExpressCap->SlotControl.Bits.PowerIndicator] + ); + ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower "); + if ( + PciExpressCap->SlotControl.Bits.PowerController) { + ShellPrintEx (-1, -1, L"Off%N\r\n"); + } else { + ShellPrintEx (-1, -1, L"On%N\r\n"); + } + ShellPrintEx (-1, -1, + L" Electromechanical Interlock Control(11): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.ElectromechanicalInterlock + ); + ShellPrintEx (-1, -1, + L" Data Link Layer State Changed Enable(12): %E%d%N\r\n", + PciExpressCap->SlotControl.Bits.DataLinkLayerStateChanged + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device slot status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieSlotStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" Attention Button Pressed(0): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.AttentionButtonPressed + ); + ShellPrintEx (-1, -1, + L" Power Fault Detected(1): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.PowerFaultDetected + ); + ShellPrintEx (-1, -1, + L" MRL Sensor Changed(2): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.MrlSensorChanged + ); + ShellPrintEx (-1, -1, + L" Presence Detect Changed(3): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.PresenceDetectChanged + ); + ShellPrintEx (-1, -1, + L" Command Completed(4): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.CommandCompleted + ); + ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL "); + if ( + PciExpressCap->SlotStatus.Bits.MrlSensor) { + ShellPrintEx (-1, -1, L" Opened%N\r\n"); + } else { + ShellPrintEx (-1, -1, L" Closed%N\r\n"); + } + ShellPrintEx (-1, -1, L" Presence Detect State(6): "); + if ( + PciExpressCap->SlotStatus.Bits.PresenceDetect) { + ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n"); + } else { + ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n"); + } + ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock "); + if ( + PciExpressCap->SlotStatus.Bits.ElectromechanicalInterlock) { + ShellPrintEx (-1, -1, L"Engaged%N\r\n"); + } else { + ShellPrintEx (-1, -1, L"Disengaged%N\r\n"); + } + ShellPrintEx (-1, -1, + L" Data Link Layer State Changed(8): %E%d%N\r\n", + PciExpressCap->SlotStatus.Bits.DataLinkLayerStateChanged + ); + return EFI_SUCCESS; +} + +/** + Print out information of the device root information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootControl ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" System Error on Correctable Error Enable(0): %E%d%N\r\n", + PciExpressCap->RootControl.Bits.SystemErrorOnCorrectableError + ); + ShellPrintEx (-1, -1, + L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n", + PciExpressCap->RootControl.Bits.SystemErrorOnNonFatalError + ); + ShellPrintEx (-1, -1, + L" System Error on Fatal Error Enable(2): %E%d%N\r\n", + PciExpressCap->RootControl.Bits.SystemErrorOnFatalError + ); + ShellPrintEx (-1, -1, + L" PME Interrupt Enable(3): %E%d%N\r\n", + PciExpressCap->RootControl.Bits.PmeInterrupt + ); + ShellPrintEx (-1, -1, + L" CRS Software Visibility Enable(4): %E%d%N\r\n", + PciExpressCap->RootControl.Bits.CrsSoftwareVisibility + ); + + return EFI_SUCCESS; +} + +/** + Print out information of the device root capability information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootCap ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" CRS Software Visibility(0): %E%d%N\r\n", + PciExpressCap->RootCapability.Bits.CrsSoftwareVisibility + ); + + return EFI_SUCCESS; +} + +/** + Print out information of the device root status information. + + @param[in] PciExpressCap The pointer to the structure about the device. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +ExplainPcieRootStatus ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + ShellPrintEx (-1, -1, + L" PME Requester ID(15:0): %E0x%04x%N\r\n", + PciExpressCap->RootStatus.Bits.PmeRequesterId + ); + ShellPrintEx (-1, -1, + L" PME Status(16): %E%d%N\r\n", + PciExpressCap->RootStatus.Bits.PmeStatus + ); + ShellPrintEx (-1, -1, + L" PME Pending(17): %E%d%N\r\n", + PciExpressCap->RootStatus.Bits.PmePending + ); + return EFI_SUCCESS; +} + +/** + Function to interpret and print out the link control structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityLinkControl ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_LINK_CONTROL), + gShellDebug1HiiHandle, + Header->RootComplexLinkCapabilities, + Header->RootComplexLinkControl, + Header->RootComplexLinkStatus + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the power budgeting structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityPowerBudgeting ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_POWER), + gShellDebug1HiiHandle, + Header->DataSelect, + Header->Data, + Header->PowerBudgetCapability + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the ACS structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityAcs ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED *Header; + UINT16 VectorSize; + UINT16 LoopCounter; + + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED*)HeaderAddress; + VectorSize = 0; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_ACS), + gShellDebug1HiiHandle, + Header->AcsCapability, + Header->AcsControl + ); + if (PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(Header)) { + VectorSize = PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(Header); + if (VectorSize == 0) { + VectorSize = 256; + } + for (LoopCounter = 0 ; LoopCounter * 8 < VectorSize ; LoopCounter++) { + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_ACS2), + gShellDebug1HiiHandle, + LoopCounter + 1, + Header->EgressControlVectorArray[LoopCounter] + ); + } + } + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED) + (VectorSize / 8) - 1, + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the latency tolerance reporting structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityLatencyToleranceReporting ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_LAT), + gShellDebug1HiiHandle, + Header->MaxSnoopLatency, + Header->MaxNoSnoopLatency + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the serial number structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilitySerialNumber ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_SN), + gShellDebug1HiiHandle, + Header->SerialNumber + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the RCRB structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityRcrb ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_RCRB), + gShellDebug1HiiHandle, + Header->VendorId, + Header->DeviceId, + Header->RcrbCapabilities, + Header->RcrbControl + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the vendor specific structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityVendorSpecific ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_VEN), + gShellDebug1HiiHandle, + Header->VendorSpecificHeader + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(Header), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the Event Collector Endpoint Association structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityECEA ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_ECEA), + gShellDebug1HiiHandle, + Header->AssociationBitmap + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the ARI structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityAri ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_ARI), + gShellDebug1HiiHandle, + Header->AriCapability, + Header->AriControl + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the DPA structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityDynamicPowerAllocation ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION *Header; + UINT8 LinkCount; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_DPA), + gShellDebug1HiiHandle, + Header->DpaCapability, + Header->DpaLatencyIndicator, + Header->DpaStatus, + Header->DpaControl + ); + for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header) + 1 ; LinkCount++) { + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_DPA2), + gShellDebug1HiiHandle, + LinkCount+1, + Header->DpaPowerAllocationArray[LinkCount] + ); + } + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION) - 1 + PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the link declaration structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityLinkDeclaration ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION *Header; + UINT8 LinkCount; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR), + gShellDebug1HiiHandle, + Header->ElementSelfDescription + ); + + for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header) ; LinkCount++) { + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR2), + gShellDebug1HiiHandle, + LinkCount+1, + Header->LinkEntry[LinkCount] + ); + } + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION) + (PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header)-1)*sizeof(UINT32), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the Advanced Error Reporting structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityAer ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_AER), + gShellDebug1HiiHandle, + Header->UncorrectableErrorStatus, + Header->UncorrectableErrorMask, + Header->UncorrectableErrorSeverity, + Header->CorrectableErrorStatus, + Header->CorrectableErrorMask, + Header->AdvancedErrorCapabilitiesAndControl, + Header->HeaderLog[0], + Header->HeaderLog[1], + Header->HeaderLog[2], + Header->HeaderLog[3], + Header->RootErrorCommand, + Header->RootErrorStatus, + Header->ErrorSourceIdentification, + Header->CorrectableErrorSourceIdentification, + Header->TlpPrefixLog[0], + Header->TlpPrefixLog[1], + Header->TlpPrefixLog[2], + Header->TlpPrefixLog[3] + ); + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING), + (VOID *) (HeaderAddress) + ); + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the multicast structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. + @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityMulticast ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, + IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_MULTICAST), + gShellDebug1HiiHandle, + Header->MultiCastCapability, + Header->MulticastControl, + Header->McBaseAddress, + Header->McReceiveAddress, + Header->McBlockAll, + Header->McBlockUntranslated, + Header->McOverlayBar + ); + + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST), + (VOID *) (HeaderAddress) + ); + + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the virtual channel and multi virtual channel structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityVirtualChannel ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY *Header; + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC *CapabilityItem; + UINT32 ItemCount; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_VC_BASE), + gShellDebug1HiiHandle, + Header->ExtendedVcCount, + Header->PortVcCapability1, + Header->PortVcCapability2, + Header->VcArbTableOffset, + Header->PortVcControl, + Header->PortVcStatus + ); + for (ItemCount = 0 ; ItemCount < Header->ExtendedVcCount ; ItemCount++) { + CapabilityItem = &Header->Capability[ItemCount]; + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_VC_ITEM), + gShellDebug1HiiHandle, + ItemCount+1, + CapabilityItem->VcResourceCapability, + CapabilityItem->PortArbTableOffset, + CapabilityItem->VcResourceControl, + CapabilityItem->VcResourceStatus + ); + } + + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY) + + Header->ExtendedVcCount * sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC), + (VOID *) (HeaderAddress) + ); + + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the resizeable bar structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityResizeableBar ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR *Header; + UINT32 ItemCount; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR*)HeaderAddress; + + for (ItemCount = 0 ; ItemCount < (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) ; ItemCount++) { + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_RESIZE_BAR), + gShellDebug1HiiHandle, + ItemCount+1, + Header->Capability[ItemCount].ResizableBarCapability.Uint32, + Header->Capability[ItemCount].ResizableBarControl.Uint32 + ); + } + + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY), + (VOID *) (HeaderAddress) + ); + + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the TPH structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilityTph ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_TPH), + gShellDebug1HiiHandle, + Header->TphRequesterCapability, + Header->TphRequesterControl + ); + DumpHex ( + 8, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->TphStTable - (UINT8*)HeadersBaseAddress), + GET_TPH_TABLE_SIZE(Header), + (VOID *)Header->TphStTable + ); + + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) + GET_TPH_TABLE_SIZE(Header) - sizeof(UINT16), + (VOID *) (HeaderAddress) + ); + + return (EFI_SUCCESS); +} + +/** + Function to interpret and print out the secondary PCIe capability structure + + @param[in] HeaderAddress The Address of this capability header. + @param[in] HeadersBaseAddress The address of all the extended capability headers. + @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. +**/ +EFI_STATUS +PrintInterpretedExtendedCompatibilitySecondary ( + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, + IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCap + ) +{ + CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE *Header; + Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE*)HeaderAddress; + + ShellPrintHiiEx( + -1, -1, NULL, + STRING_TOKEN (STR_PCI_EXT_CAP_SECONDARY), + gShellDebug1HiiHandle, + Header->LinkControl3.Uint32, + Header->LaneErrorStatus + ); + DumpHex ( + 8, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->EqualizationControl - (UINT8*)HeadersBaseAddress), + PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL), + (VOID *)Header->EqualizationControl + ); + + DumpHex ( + 4, + EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress), + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE) - sizeof (Header->EqualizationControl) + + PciExpressCap->LinkCapability.Bits.MaxLinkWidth * sizeof (PCI_EXPRESS_REG_LANE_EQUALIZATION_CONTROL), + (VOID *) (HeaderAddress) + ); + + return (EFI_SUCCESS); +} + +/** + Display Pcie extended capability details + + @param[in] HeadersBaseAddress The address of all the extended capability headers. + @param[in] HeaderAddress The address of this capability header. + @param[in] PciExpressCapPtr The address of the PCIe capabilities structure. +**/ +EFI_STATUS +PrintPciExtendedCapabilityDetails( + IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress, + IN CONST PCI_EXP_EXT_HDR *HeaderAddress, + IN CONST PCI_CAPABILITY_PCIEXP *PciExpressCapPtr + ) +{ + switch (HeaderAddress->CapabilityId){ + case PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID: + return PrintInterpretedExtendedCompatibilityAer(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID: + return PrintInterpretedExtendedCompatibilityLinkControl(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID: + return PrintInterpretedExtendedCompatibilityLinkDeclaration(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID: + return PrintInterpretedExtendedCompatibilitySerialNumber(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID: + return PrintInterpretedExtendedCompatibilityPowerBudgeting(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID: + return PrintInterpretedExtendedCompatibilityAcs(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID: + return PrintInterpretedExtendedCompatibilityLatencyToleranceReporting(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID: + return PrintInterpretedExtendedCompatibilityAri(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID: + return PrintInterpretedExtendedCompatibilityRcrb(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID: + return PrintInterpretedExtendedCompatibilityVendorSpecific(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID: + return PrintInterpretedExtendedCompatibilityDynamicPowerAllocation(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID: + return PrintInterpretedExtendedCompatibilityECEA(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID: + case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID: + return PrintInterpretedExtendedCompatibilityVirtualChannel(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID: + // + // should only be present if PCIE_CAP_DEVICEPORT_TYPE(PciExpressCapPtr->PcieCapReg) == 0100b, 0101b, or 0110b + // + return PrintInterpretedExtendedCompatibilityMulticast(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr); + case PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID: + return PrintInterpretedExtendedCompatibilityResizeableBar(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID: + return PrintInterpretedExtendedCompatibilityTph(HeaderAddress, HeadersBaseAddress); + case PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID: + return PrintInterpretedExtendedCompatibilitySecondary(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr); + default: + ShellPrintEx (-1, -1, + L"Unknown PCIe extended capability ID (%04xh). No interpretation available.\r\n", + HeaderAddress->CapabilityId + ); + return EFI_SUCCESS; + }; + +} + +/** + Display Pcie device structure. + + @param[in] PciExpressCap PCI Express capability buffer. + @param[in] ExtendedConfigSpace PCI Express extended configuration space. + @param[in] ExtendedConfigSize PCI Express extended configuration size. + @param[in] ExtendedCapability PCI Express extended capability ID to explain. +**/ +VOID +PciExplainPciExpress ( + IN PCI_CAPABILITY_PCIEXP *PciExpressCap, + IN UINT8 *ExtendedConfigSpace, + IN UINTN ExtendedConfigSize, + IN CONST UINT16 ExtendedCapability + ) +{ + UINT8 DevicePortType; + UINTN Index; + UINT8 *RegAddr; + UINTN RegValue; + PCI_EXP_EXT_HDR *ExtHdr; + + DevicePortType = (UINT8)PciExpressCap->Capability.Bits.DevicePortType; + + ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n"); + + for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) { + if (ShellGetExecutionBreakFlag()) { + return; + } + RegAddr = (UINT8 *) PciExpressCap + PcieExplainList[Index].Offset; + switch (PcieExplainList[Index].Width) { + case FieldWidthUINT8: + RegValue = *(UINT8 *) RegAddr; + break; + case FieldWidthUINT16: + RegValue = *(UINT16 *) RegAddr; + break; + case FieldWidthUINT32: + RegValue = *(UINT32 *) RegAddr; + break; + default: + RegValue = 0; + break; + } + ShellPrintHiiEx(-1, -1, NULL, + PcieExplainList[Index].Token, + gShellDebug1HiiHandle, + PcieExplainList[Index].Offset, + RegValue + ); + if (PcieExplainList[Index].Func == NULL) { + continue; + } + switch (PcieExplainList[Index].Type) { + case PcieExplainTypeLink: + // + // Link registers should not be used by + // a) Root Complex Integrated Endpoint + // b) Root Complex Event Collector + // + if (DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT || + DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR) { + continue; + } + break; + case PcieExplainTypeSlot: + // + // Slot registers are only valid for + // a) Root Port of PCI Express Root Complex + // b) Downstream Port of PCI Express Switch + // and when SlotImplemented bit is set in PCIE cap register. + // + if ((DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT && + DevicePortType != PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT) || + !PciExpressCap->Capability.Bits.SlotImplemented) { + continue; + } + break; + case PcieExplainTypeRoot: + // + // Root registers are only valid for + // Root Port of PCI Express Root Complex + // + if (DevicePortType != PCIE_DEVICE_PORT_TYPE_ROOT_PORT) { + continue; + } + break; + default: + break; + } + PcieExplainList[Index].Func (PciExpressCap); + } + + ExtHdr = (PCI_EXP_EXT_HDR*)ExtendedConfigSpace; + while (ExtHdr->CapabilityId != 0 && ExtHdr->CapabilityVersion != 0 && ExtHdr->CapabilityId != 0xFFFF) { + // + // Process this item + // + if (ExtendedCapability == 0xFFFF || ExtendedCapability == ExtHdr->CapabilityId) { + // + // Print this item + // + PrintPciExtendedCapabilityDetails((PCI_EXP_EXT_HDR*)ExtendedConfigSpace, ExtHdr, PciExpressCap); + } + + // + // Advance to the next item if it exists + // + if (ExtHdr->NextCapabilityOffset != 0 && + (ExtHdr->NextCapabilityOffset <= (UINT32) (ExtendedConfigSize + EFI_PCIE_CAPABILITY_BASE_OFFSET - sizeof (PCI_EXP_EXT_HDR)))) { + ExtHdr = (PCI_EXP_EXT_HDR*)(ExtendedConfigSpace + ExtHdr->NextCapabilityOffset - EFI_PCIE_CAPABILITY_BASE_OFFSET); + } else { + break; + } + } +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h new file mode 100644 index 00000000..3a7e1ad7 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h @@ -0,0 +1,58 @@ +/** @file + Header file for Pci shell Debug1 function. + + Copyright (c) 2013 Hewlett-Packard Development Company, L.P. + Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_SHELL_PCI_H_ +#define _EFI_SHELL_PCI_H_ + +typedef enum { + PciDevice, + PciP2pBridge, + PciCardBusBridge, + PciUndefined +} PCI_HEADER_TYPE; + +#define INDEX_OF(Field) ((UINT8 *) (Field) - (UINT8 *) mConfigSpace) + +#define IS_PCIE_ENDPOINT(DevicePortType) \ + ((DevicePortType) == PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT || \ + (DevicePortType) == PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT || \ + (DevicePortType) == PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT) + +#define IS_PCIE_SWITCH(DevicePortType) \ + ((DevicePortType == PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) || \ + (DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT)) + +#pragma pack(1) +// +// Data region after PCI configuration header(for cardbus bridge) +// +typedef struct { + UINT16 SubVendorId; // Subsystem Vendor ID + UINT16 SubSystemId; // Subsystem ID + UINT32 LegacyBase; // Optional 16-Bit PC Card Legacy + // Mode Base Address + // + UINT32 Data[46]; +} PCI_CARDBUS_DATA; + +typedef union { + PCI_DEVICE_HEADER_TYPE_REGION Device; + PCI_BRIDGE_CONTROL_REGISTER Bridge; + PCI_CARDBUS_CONTROL_REGISTER CardBus; +} NON_COMMON_UNION; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Common; + NON_COMMON_UNION NonCommon; + UINT32 Data[48]; +} PCI_CONFIG_SPACE; + +#pragma pack() + +#endif // _PCI_H_ diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SerMode.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SerMode.c new file mode 100644 index 00000000..c2955063 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SerMode.c @@ -0,0 +1,365 @@ +/** @file + Main file for SerMode shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Library/ShellLib.h> +#include <Protocol/SerialIo.h> + +/** + Display information about a serial device by it's handle. + + If HandleValid is FALSE, do all devices. + + @param[in] HandleIdx The handle index for the device. + @param[in] HandleValid TRUE if HandleIdx is valid. + + @retval SHELL_INVALID_PARAMETER A parameter was invalid. + @retval SHELL_SUCCESS The operation was successful. +**/ +SHELL_STATUS +DisplaySettings ( + IN UINTN HandleIdx, + IN BOOLEAN HandleValid + ) +{ + EFI_SERIAL_IO_PROTOCOL *SerialIo; + UINTN NoHandles; + EFI_HANDLE *Handles; + EFI_STATUS Status; + UINTN Index; + CHAR16 *StopBits; + CHAR16 Parity; + SHELL_STATUS ShellStatus; + + Handles = NULL; + StopBits = NULL; + + ShellStatus = SHELL_SUCCESS; + + Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); + return SHELL_INVALID_PARAMETER; + } + + for (Index = 0; Index < NoHandles; Index++) { + if (HandleValid) { + if (ConvertHandleIndexToHandle(HandleIdx) != Handles[Index]) { + continue; + } + } + + Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo); + if (!EFI_ERROR (Status)) { + switch (SerialIo->Mode->Parity) { + case DefaultParity: + + Parity = 'D'; + break; + + case NoParity: + + Parity = 'N'; + break; + + case EvenParity: + + Parity = 'E'; + break; + + case OddParity: + + Parity = 'O'; + break; + + case MarkParity: + + Parity = 'M'; + break; + + case SpaceParity: + + Parity = 'S'; + break; + + default: + + Parity = 'U'; + } + + switch (SerialIo->Mode->StopBits) { + case DefaultStopBits: + + StopBits = L"Default"; + break; + + case OneStopBit: + + StopBits = L"1"; + break; + + case TwoStopBits: + + StopBits = L"2"; + break; + + case OneFiveStopBits: + + StopBits = L"1.5"; + break; + + default: + + StopBits = L"Unknown"; + } + ShellPrintHiiEx( + -1, + -1, + NULL, + STRING_TOKEN (STR_SERMODE_DISPLAY), + gShellDebug1HiiHandle, + ConvertHandleToHandleIndex (Handles[Index]), + Handles[Index], + SerialIo->Mode->BaudRate, + Parity, + SerialIo->Mode->DataBits, + StopBits + ); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); + ShellStatus = SHELL_NOT_FOUND; + break; + } + + if (HandleValid) { + break; + } + } + + if (Index == NoHandles) { + if ((NoHandles != 0 && HandleValid) || 0 == NoHandles) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NOT_FOUND), gShellDebug1HiiHandle, L"sermode"); + ShellStatus = SHELL_NOT_FOUND; + } + } + + return ShellStatus; +} + +/** + Function for 'sermode' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSerMode ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + UINTN Index; + UINTN NoHandles; + EFI_HANDLE *Handles; + EFI_PARITY_TYPE Parity; + EFI_STOP_BITS_TYPE StopBits; + UINTN HandleIdx; + UINTN BaudRate; + UINTN DataBits; + UINTN Value; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + CONST CHAR16 *Temp; + UINT64 Intermediate; + + ShellStatus = SHELL_SUCCESS; + HandleIdx = 0; + Parity = DefaultParity; + Handles = NULL; + NoHandles = 0; + Index = 0; + Package = NULL; + + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"sermode", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) < 6 && ShellCommandLineGetCount(Package) > 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"sermode"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetCount(Package) > 6) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"sermode"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + Temp = ShellCommandLineGetRawValue(Package, 1); + if (Temp != NULL) { + Status = ShellConvertStringToUint64(Temp, &Intermediate, TRUE, FALSE); + HandleIdx = (UINTN)Intermediate; + Temp = ShellCommandLineGetRawValue(Package, 2); + if (Temp == NULL) { + ShellStatus = DisplaySettings (HandleIdx, TRUE); + goto Done; + } + } else { + ShellStatus = DisplaySettings (0, FALSE); + goto Done; + } + Temp = ShellCommandLineGetRawValue(Package, 2); + if (Temp != NULL) { + BaudRate = ShellStrToUintn(Temp); + } else { + ASSERT(FALSE); + BaudRate = 0; + } + Temp = ShellCommandLineGetRawValue(Package, 3); + if (Temp == NULL || StrLen(Temp)>1) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + switch(Temp[0]){ + case 'd': + case 'D': + Parity = DefaultParity; + break; + case 'n': + case 'N': + Parity = NoParity; + break; + case 'e': + case 'E': + Parity = EvenParity; + break; + case 'o': + case 'O': + Parity = OddParity; + break; + case 'm': + case 'M': + Parity = MarkParity; + break; + case 's': + case 'S': + Parity = SpaceParity; + break; + default: + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + } + Temp = ShellCommandLineGetRawValue(Package, 4); + if (Temp != NULL) { + DataBits = ShellStrToUintn(Temp); + } else { + // + // make sure this is some number not in the list below. + // + DataBits = 0; + } + switch (DataBits) { + case 4: + case 7: + case 8: + break; + default: + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + Temp = ShellCommandLineGetRawValue(Package, 5); + Value = ShellStrToUintn(Temp); + switch (Value) { + case 0: + StopBits = DefaultStopBits; + break; + + case 1: + StopBits = OneStopBit; + break; + + case 2: + StopBits = TwoStopBits; + break; + + case 15: + StopBits = OneFiveStopBits; + break; + + default: + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); + ShellStatus = SHELL_INVALID_PARAMETER; + goto Done; + } + + for (Index = 0; Index < NoHandles; Index++) { + if (ConvertHandleIndexToHandle (HandleIdx) != Handles[Index]) { + continue; + } + + Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo); + if (!EFI_ERROR (Status)) { + Status = SerialIo->SetAttributes ( + SerialIo, + (UINT64) BaudRate, + SerialIo->Mode->ReceiveFifoDepth, + SerialIo->Mode->Timeout, + Parity, + (UINT8) DataBits, + StopBits + ); + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_UNSUPPORTED), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); + ShellStatus = SHELL_UNSUPPORTED; + } else if (Status == EFI_DEVICE_ERROR) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_DEV_ERROR), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); + ShellStatus = SHELL_ACCESS_DENIED; + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_FAIL), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); + ShellStatus = SHELL_ACCESS_DENIED; + } + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_HANDLE), gShellDebug1HiiHandle, ConvertHandleToHandleIndex(Handles[Index])); + } + break; + } + } + } + } + + if (ShellStatus == SHELL_SUCCESS && Index == NoHandles) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_BAD_HANDLE), gShellDebug1HiiHandle, L"sermode", HandleIdx); + ShellStatus = SHELL_INVALID_PARAMETER; + } + +Done: + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + if (Handles != NULL) { + FreePool (Handles); + } + return ShellStatus; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetSize.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetSize.c new file mode 100644 index 00000000..09250b09 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetSize.c @@ -0,0 +1,104 @@ +/** @file + Main file for SetSize shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" + +/** + Function for 'setsize' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSetSize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Temp1; + UINTN NewSize; + UINTN LoopVar; + SHELL_FILE_HANDLE FileHandle; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); + if (EFI_ERROR(Status)) { + if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setsize", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) < 3) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setsize"); + ShellStatus = SHELL_INVALID_PARAMETER; + NewSize = 0; + } else { + Temp1 = ShellCommandLineGetRawValue(Package, 1); + if (!ShellIsHexOrDecimalNumber(Temp1, FALSE, FALSE)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SIZE_NOT_SPEC), gShellDebug1HiiHandle, L"setsize"); + ShellStatus = SHELL_INVALID_PARAMETER; + NewSize = 0; + } else { + NewSize = ShellStrToUintn(Temp1); + } + } + for (LoopVar = 2 ; LoopVar < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS ; LoopVar++) { + Status = ShellOpenFileByName(ShellCommandLineGetRawValue(Package, LoopVar), &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); + if (EFI_ERROR(Status)) { + Status = ShellOpenFileByName(ShellCommandLineGetRawValue(Package, LoopVar), &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + } + if (EFI_ERROR(Status) && LoopVar == 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_SPEC), gShellDebug1HiiHandle, L"setsize"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"setsize", ShellCommandLineGetRawValue(Package, LoopVar)); + ShellStatus = SHELL_INVALID_PARAMETER; + break; + } else { + Status = FileHandleSetSize(FileHandle, NewSize); + if (Status == EFI_VOLUME_FULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_VOLUME_FULL), gShellDebug1HiiHandle, L"setsize"); + ShellStatus = SHELL_VOLUME_FULL; + } else if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SET_SIZE_FAIL), gShellDebug1HiiHandle, L"setsize", ShellCommandLineGetRawValue(Package, LoopVar)); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SET_SIZE_DONE), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, LoopVar)); + } + ShellCloseFile(&FileHandle); + } + } + + ShellCommandLineFreeVarList (Package); + } + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c new file mode 100644 index 00000000..0ec6edff --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c @@ -0,0 +1,469 @@ +/** @file + Main file for SetVar shell Debug1 function. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-guid", TypeValue}, + {L"-bs", TypeFlag}, + {L"-rt", TypeFlag}, + {L"-nv", TypeFlag}, + {NULL, TypeMax} + }; + +typedef enum { + DataTypeHexNumber = 0, + DataTypeHexArray = 1, + DataTypeAscii = 2, + DataTypeUnicode = 3, + DataTypeDevicePath = 4, + DataTypeUnKnow = 5 +} DATA_TYPE; + +typedef union { + UINT8 HexNumber8; + UINT16 HexNumber16; + UINT32 HexNumber32; + UINT64 HexNumber64; +} HEX_NUMBER; + +/** + Check if the input is a (potentially empty) string of hexadecimal nibbles. + + @param[in] String The CHAR16 string to check. + + @retval FALSE A character has been found in String for which + ShellIsHexaDecimalDigitCharacter() returned FALSE. + + @retval TRUE Otherwise. (Note that this covers the case when String is + empty.) +**/ +BOOLEAN +IsStringOfHexNibbles ( + IN CONST CHAR16 *String + ) +{ + CONST CHAR16 *Pos; + + for (Pos = String; *Pos != L'\0'; ++Pos) { + if (!ShellIsHexaDecimalDigitCharacter (*Pos)) { + return FALSE; + } + } + return TRUE; +} + +/** + Function to check the TYPE of Data. + + @param[in] Data The Data to be check. + + @retval DATA_TYPE The TYPE of Data. +**/ +DATA_TYPE +TestDataType ( + IN CONST CHAR16 *Data + ) +{ + if (Data[0] == L'0' && (Data[1] == L'x' || Data[1] == L'X')) { + if (IsStringOfHexNibbles (Data+2) && StrLen (Data + 2) <= 16) { + return DataTypeHexNumber; + } else { + return DataTypeUnKnow; + } + } else if (Data[0] == L'H') { + if (IsStringOfHexNibbles (Data + 1) && StrLen (Data + 1) % 2 == 0) { + return DataTypeHexArray; + } else { + return DataTypeUnKnow; + } + } else if (Data[0] == L'S') { + return DataTypeAscii; + } else if (Data[0] == L'L') { + return DataTypeUnicode; + } else if (Data[0] == L'P' || StrnCmp (Data, L"--", 2) == 0) { + return DataTypeDevicePath; + } + + if (IsStringOfHexNibbles (Data) && StrLen (Data) % 2 == 0) { + return DataTypeHexArray; + } + + return DataTypeAscii; +} + +/** + Function to parse the Data by the type of Data, and save in the Buffer. + + @param[in] Data A pointer to a buffer to be parsed. + @param[out] Buffer A pointer to a buffer to hold the return data. + @param[in,out] BufferSize On input, indicates the size of Buffer in bytes. + On output,indicates the size of data return in Buffer. + Or the size in bytes of the buffer needed to obtain. + + @retval EFI_INVALID_PARAMETER The Buffer or BufferSize is NULL. + @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to hold the data. + @retval EFI_OUT_OF_RESOURCES A memory allcation failed. + @retval EFI_SUCCESS The Data parsed successful and save in the Buffer. +**/ +EFI_STATUS +ParseParameterData ( + IN CONST CHAR16 *Data, + OUT VOID *Buffer, + IN OUT UINTN *BufferSize + ) +{ + UINT64 HexNumber; + UINTN HexNumberLen; + UINTN Size; + CHAR8 *AsciiBuffer; + DATA_TYPE DataType; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_STATUS Status; + + HexNumber = 0; + HexNumberLen = 0; + Size = 0; + AsciiBuffer = NULL; + DevPath = NULL; + Status = EFI_SUCCESS; + + if (Data == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + DataType = TestDataType (Data); + if (DataType == DataTypeHexNumber) { + // + // hex number + // + StrHexToUint64S (Data + 2, NULL, &HexNumber); + HexNumberLen = StrLen (Data + 2); + if (HexNumberLen >= 1 && HexNumberLen <= 2) { + Size = 1; + } else if (HexNumberLen >= 3 && HexNumberLen <= 4) { + Size = 2; + } else if (HexNumberLen >= 5 && HexNumberLen <= 8) { + Size = 4; + } else if (HexNumberLen >= 9 && HexNumberLen <= 16) { + Size = 8; + } + if (Buffer != NULL && *BufferSize >= Size) { + CopyMem(Buffer, (VOID *)&HexNumber, Size); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + } else if (DataType == DataTypeHexArray) { + // + // hex array + // + if (*Data == L'H') { + Data = Data + 1; + } + + Size = StrLen (Data) / 2; + if (Buffer != NULL && *BufferSize >= Size) { + StrHexToBytes(Data, StrLen (Data), (UINT8 *)Buffer, Size); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + } else if (DataType == DataTypeAscii) { + // + // ascii text + // + if (*Data == L'S') { + Data = Data + 1; + } + AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2); + if (AsciiBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data); + + Size = StrSize (Data) / 2 - 1; + if (Buffer != NULL && *BufferSize >= Size) { + CopyMem (Buffer, AsciiBuffer, Size); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + } + SHELL_FREE_NON_NULL (AsciiBuffer); + } else if (DataType == DataTypeUnicode) { + // + // unicode text + // + if (*Data == L'L') { + Data = Data + 1; + } + Size = StrSize (Data) - sizeof (CHAR16); + if (Buffer != NULL && *BufferSize >= Size) { + CopyMem (Buffer, Data, Size); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + } else if (DataType == DataTypeDevicePath) { + if (*Data == L'P') { + Data = Data + 1; + } else if (StrnCmp (Data, L"--", 2) == 0) { + Data = Data + 2; + } + DevPath = ConvertTextToDevicePath (Data); + if (DevPath == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar"); + Status = EFI_INVALID_PARAMETER; + } else { + Size = GetDevicePathSize (DevPath); + if (Buffer != NULL && *BufferSize >= Size) { + CopyMem (Buffer, DevPath, Size); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + *BufferSize = Size; + } + SHELL_FREE_NON_NULL (DevPath); + } else { + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} + +/** + Function to get each data from parameters. + + @param[in] Package The package of checked values. + @param[out] Buffer A pointer to a buffer to hold the return data. + @param[out] BufferSize Indicates the size of data in bytes return in Buffer. + + @retval EFI_INVALID_PARAMETER Buffer or BufferSize is NULL. + @retval EFI_OUT_OF_RESOURCES A memory allcation failed. + @retval EFI_SUCCESS Get each parameter data was successful. +**/ +EFI_STATUS +GetVariableDataFromParameter ( + IN CONST LIST_ENTRY *Package, + OUT UINT8 **Buffer, + OUT UINTN *BufferSize + ) +{ + CONST CHAR16 *TempData; + UINTN Index; + UINTN TotalSize; + UINTN Size; + UINT8 *BufferWalker; + EFI_STATUS Status; + + TotalSize = 0; + Size = 0; + Status = EFI_SUCCESS; + + if (BufferSize == NULL || Buffer == NULL || ShellCommandLineGetCount (Package) < 3) { + return EFI_INVALID_PARAMETER; + } + + for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) { + TempData = ShellCommandLineGetRawValue (Package, Index); + ASSERT (TempData != NULL); + + if (TempData[0] != L'=') { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData); + return EFI_INVALID_PARAMETER; + } + + TempData = TempData + 1; + Size = 0; + Status = ParseParameterData (TempData, NULL, &Size); + if (EFI_ERROR (Status)) { + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData. + // + TotalSize += Size; + } else { + if (Status == EFI_INVALID_PARAMETER) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData); + } else if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar"); + } + return Status; + } + } + } + + *BufferSize = TotalSize; + *Buffer = AllocateZeroPool (TotalSize); + + if (*Buffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + BufferWalker = *Buffer; + for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) { + TempData = ShellCommandLineGetRawValue (Package, Index); + TempData = TempData + 1; + + Size = TotalSize; + Status = ParseParameterData (TempData, (VOID *)BufferWalker, &Size); + if (!EFI_ERROR (Status)) { + BufferWalker = BufferWalker + Size; + TotalSize = TotalSize - Size; + } else { + return Status; + } + } + } + + return EFI_SUCCESS; +} + +/** + Function for 'setvar' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSetVar ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + RETURN_STATUS RStatus; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *VariableName; + EFI_GUID Guid; + CONST CHAR16 *StringGuid; + UINT32 Attributes; + VOID *Buffer; + UINTN Size; + UINTN LoopVar; + + ShellStatus = SHELL_SUCCESS; + Status = EFI_SUCCESS; + Buffer = NULL; + Size = 0; + Attributes = 0; + + // + // initialize the shell lib (we must be in non-auto-init...) + // + Status = ShellInitialize(); + ASSERT_EFI_ERROR(Status); + + Status = CommandInit(); + ASSERT_EFI_ERROR(Status); + + // + // parse the command line + // + 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), gShellDebug1HiiHandle, L"setvar", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else if (ShellCommandLineCheckDuplicate (Package,&ProblemParam) != EFI_SUCCESS) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DUPLICATE), gShellDebug1HiiHandle, L"setvar", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + if (ShellCommandLineGetCount(Package) < 2) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + VariableName = ShellCommandLineGetRawValue(Package, 1); + if (!ShellCommandLineGetFlag(Package, L"-guid")){ + CopyGuid(&Guid, &gEfiGlobalVariableGuid); + } else { + StringGuid = ShellCommandLineGetValue(Package, L"-guid"); + RStatus = StrToGuid (StringGuid, &Guid); + if (RETURN_ERROR (RStatus) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid); + ShellStatus = SHELL_INVALID_PARAMETER; + } + } + + if (ShellCommandLineGetCount(Package) == 2) { + // + // Display + // + Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = AllocateZeroPool(Size); + Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); + } + if (!EFI_ERROR(Status) && Buffer != NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size); + for (LoopVar = 0; LoopVar < Size; LoopVar++) { + ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]); + } + ShellPrintEx(-1, -1, L"\r\n"); + } else { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName); + ShellStatus = SHELL_ACCESS_DENIED; + } + } else { + // + // Create, Delete or Modify. + // + Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = AllocateZeroPool(Size); + Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); + } + if (EFI_ERROR(Status) || Buffer == NULL) { + // + // Creating a new variable. determine attributes from command line. + // + Attributes = 0; + if (ShellCommandLineGetFlag(Package, L"-bs")) { + Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS; + } + if (ShellCommandLineGetFlag(Package, L"-rt")) { + Attributes |= EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS; + } + if (ShellCommandLineGetFlag(Package, L"-nv")) { + Attributes |= EFI_VARIABLE_NON_VOLATILE; + } + } + SHELL_FREE_NON_NULL(Buffer); + + Size = 0; + Status = GetVariableDataFromParameter(Package, (UINT8 **)&Buffer, &Size); + if (!EFI_ERROR(Status)) { + Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, Size, Buffer); + } + if (EFI_ERROR(Status)) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName); + ShellStatus = SHELL_ACCESS_DENIED; + } else { + ASSERT(ShellStatus == SHELL_SUCCESS); + } + } + } + ShellCommandLineFreeVarList (Package); + } + + if (Buffer != NULL) { + FreePool(Buffer); + } + + return (ShellStatus); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.c new file mode 100644 index 00000000..48b6b2c1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.c @@ -0,0 +1,409 @@ +/** @file + Module for clarifying the content of the smbios structure element info. + + Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "PrintInfo.h" +#include "QueryTable.h" +#include "EventLogInfo.h" + +/** + Function to display system event log access information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySELAccessMethod ( + IN CONST UINT8 Key, + IN CONST UINT8 Option + ) +{ + // + // Print prompt + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ACCESS_METHOD), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + + // + // Print value info + // + switch (Key) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_EIGHT_BIT), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TWO_EIGHT_BITS), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_SIXTEEN_BIT), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MEM_MAPPED_PHYS), gShellDebug1HiiHandle); + break; + + case 4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_VIA_GENERAL), gShellDebug1HiiHandle); + break; + + default: + if (Key <= 0x7f) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE_ASSIGN), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR_OEM), gShellDebug1HiiHandle); + } + } +} + +/** + Function to display system event log status information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySELLogStatus ( + UINT8 Key, + UINT8 Option + ) +{ + // + // Print prompt + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + + // + // Print value info + // + if ((Key & 0x01) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_VALID), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_VALID), gShellDebug1HiiHandle); + } + + if ((Key & 0x02) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_FULL), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_NOT_FULL), gShellDebug1HiiHandle); + } + + if ((Key & 0xFC) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_RES_BITS_NOT_ZERO), gShellDebug1HiiHandle, Key & 0xFC); + } +} + +/** + Function to display system event log header format information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySysEventLogHeaderFormat ( + UINT8 Key, + UINT8 Option + ) +{ + // + // Print prompt + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_FORMAT), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + + // + // Print value info + // + if (Key == 0x00) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_HEADER), gShellDebug1HiiHandle); + } else if (Key == 0x01) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TYPE_LOG_HEADER), gShellDebug1HiiHandle); + } else if (Key <= 0x7f) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR), gShellDebug1HiiHandle); + } +} + +/** + Display the header information for SEL log items. + + @param[in] Key The information key. + @param[in] Option The option index. +**/ +VOID +DisplaySELLogHeaderLen ( + UINT8 Key, + UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_LEN), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_VAR_D), gShellDebug1HiiHandle, Key & 0x7F); + + // + // The most-significant bit of the field specifies + // whether (0) or not (1) the record has been read + // + if ((Key & 0x80) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_READ), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_NOT_READ), gShellDebug1HiiHandle); + } +} + +/** + Display the header information for type 1 items. + + @param[in] LogHeader The buffer with the information. +**/ +VOID +DisplaySysEventLogHeaderType1 ( + IN UINT8 *LogHeader + ) +{ + LOG_HEADER_TYPE1_FORMAT *Header; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG), gShellDebug1HiiHandle); + + // + // Print Log Header Type1 Format info + // + Header = (LOG_HEADER_TYPE1_FORMAT *) (LogHeader); + + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_OEM_RESERVED), + gShellDebug1HiiHandle, + Header->OEMReserved[0], + Header->OEMReserved[1], + Header->OEMReserved[2], + Header->OEMReserved[3], + Header->OEMReserved[4] + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_TIME), gShellDebug1HiiHandle, Header->Metw); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_COUNT), gShellDebug1HiiHandle, Header->Meci); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_ADDRESS), gShellDebug1HiiHandle, Header->CMOSAddress); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_INDEX), gShellDebug1HiiHandle, Header->CMOSBitIndex); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUM_STARTING_OFF), gShellDebug1HiiHandle, Header->StartingOffset); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUN_BYTE_COUNT), gShellDebug1HiiHandle, Header->ChecksumOffset); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_RESERVED), + gShellDebug1HiiHandle, + Header->OEMReserved[0], + Header->OEMReserved[1], + Header->OEMReserved[2] + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_HEADER_REVISION), gShellDebug1HiiHandle, Header->HeaderRevision); +} + +/** + Function to display system event log header information. + + @param[in] LogHeaderFormat Format identifier. + @param[in] LogHeader Format informcation. +**/ +VOID +DisplaySysEventLogHeader ( + UINT8 LogHeaderFormat, + UINT8 *LogHeader + ) +{ + // + // Print prompt + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER), gShellDebug1HiiHandle); + + // + // Print value info + // + if (LogHeaderFormat == 0x00) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_HEADER), gShellDebug1HiiHandle); + } else if (LogHeaderFormat == 0x01) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TYPE_LOG_HEADER), gShellDebug1HiiHandle); + DisplaySysEventLogHeaderType1 (LogHeader); + } else if (LogHeaderFormat <= 0x7f) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FUTURE_ASSIGN), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR), gShellDebug1HiiHandle); + } +} + +/** + Display the El Vdf information. + + @param[in] ElVdfType The information type. + @param[in] VarData The information buffer. +**/ +VOID +DisplayElVdfInfo ( + UINT8 ElVdfType, + UINT8 *VarData + ) +{ + UINT16 *Word; + UINT32 *Dword; + + // + // Display Type Name + // + DisplaySELVarDataFormatType (ElVdfType, SHOW_DETAIL); + + // + // Display Type description + // + switch (ElVdfType) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_STD_FORMAT), gShellDebug1HiiHandle); + break; + + case 1: + Word = (UINT16 *) (VarData + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SMBIOS_STRUCT_ASSOC), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_STRUCT_HANDLE), gShellDebug1HiiHandle, *Word); + break; + + case 2: + Dword = (UINT32 *) (VarData + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword); + break; + + case 3: + Word = (UINT16 *) (VarData + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SMBIOS_STRUCT_ASSOC), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_STRUCT_HANDLE), gShellDebug1HiiHandle, *Word); + // + // Followed by a multiple-event counter + // + Dword = (UINT32 *) (VarData + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword); + break; + + case 4: + Dword = (UINT32 *) (VarData + 1); + DisplayPostResultsBitmapDw1 (*Dword, SHOW_DETAIL); + Dword++; + DisplayPostResultsBitmapDw2 (*Dword, SHOW_DETAIL); + break; + + case 5: + Dword = (UINT32 *) (VarData + 1); + DisplaySELSysManagementTypes (*Dword, SHOW_DETAIL); + break; + + case 6: + Dword = (UINT32 *) (VarData + 1); + DisplaySELSysManagementTypes (*Dword, SHOW_DETAIL); + // + // Followed by a multiple-event counter + // + Dword = (UINT32 *) (VarData + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword); + break; + + default: + if (ElVdfType <= 0x7F) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_UNUSED_AVAIL_FOR_ASSIGN), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_SYSTEM), gShellDebug1HiiHandle); + } + } +} + +/** + Function to display system event log data. + + @param[in] LogData The data information. + @param[in] LogAreaLength Length of the data. +**/ +VOID +DisplaySysEventLogData ( + UINT8 *LogData, + UINT16 LogAreaLength + ) +{ + LOG_RECORD_FORMAT *Log; + UINT8 ElVdfType; + // + // Event Log Variable Data Format Types + // + UINTN Offset; + + // + // Print prompt + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG_2), gShellDebug1HiiHandle); + + // + // Print Log info + // + Offset = 0; + Log = (LOG_RECORD_FORMAT *) LogData; + while (Log != NULL && Log->Type != END_OF_LOG && Offset < LogAreaLength) { + + if (Log != NULL) { + // + // Display Event Log Record Information + // + DisplaySELTypes (Log->Type, SHOW_DETAIL); + DisplaySELLogHeaderLen (Log->Length, SHOW_DETAIL); + + Offset += Log->Length; + // + // Display Log Header Date/Time Fields + // These fields contain the BCD representation of the date and time + // (as read from CMOS) of the occurrence of the event + // So Print as hex and represent decimal + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_DATE), gShellDebug1HiiHandle); + if (Log != NULL && Log->Year >= 80 && Log->Year <= 99) { + Print (L"19"); + } else if (Log != NULL && Log->Year <= 79) { + Print (L"20"); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ERROR), gShellDebug1HiiHandle); + // + // Get a Event Log Record + // + Log = (LOG_RECORD_FORMAT *) (LogData + Offset); + continue; + } + + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TIME_SIX_VARS), + gShellDebug1HiiHandle, + Log->Year, + Log->Month, + Log->Day, + Log->Hour, + Log->Minute, + Log->Second + ); + + // + // Display Variable Data Format + // + if (Log->Length <= (sizeof (LOG_RECORD_FORMAT) - 1)) { + // + // Get a Event Log Record + // + Log = (LOG_RECORD_FORMAT *) (LogData + Offset); + continue; + } + + ElVdfType = Log->LogVariableData[0]; + DisplayElVdfInfo (ElVdfType, Log->LogVariableData); + // + // Get a Event Log Record + // + Log = (LOG_RECORD_FORMAT *) (LogData + Offset); + } + } +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.h new file mode 100644 index 00000000..bfc2c189 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/EventLogInfo.h @@ -0,0 +1,106 @@ +/** @file + Module to clarify system event log of smbios structure. + + Copyright (c) 2005-2011, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMBIOS_EVENT_LOG_INFO_H_ +#define _SMBIOS_EVENT_LOG_INFO_H_ + +#define END_OF_LOG 0xFF + +#pragma pack(1) + +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + UINT8 LogVariableData[1]; +} LOG_RECORD_FORMAT; + +typedef struct { + UINT8 OEMReserved[5]; + UINT8 Metw; // Multiple Event Time Window + UINT8 Meci; // Multiple Event Count Increment + UINT8 CMOSAddress; // Pre-boot Event Log Reset - CMOS Address + UINT8 CMOSBitIndex; // Pre-boot Event Log Reset - CMOS Bit Index + UINT8 StartingOffset; // CMOS Checksum - Starting Offset + UINT8 ByteCount; // CMOS Checksum - Byte Count + UINT8 ChecksumOffset; // CMOS Checksum - Checksum Offset + UINT8 Reserved[3]; + UINT8 HeaderRevision; +} LOG_HEADER_TYPE1_FORMAT; + +#pragma pack() +// +// System Event Log (Type 15) +// + +/** + Function to display system event log access information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySELAccessMethod ( + IN CONST UINT8 Key, + IN CONST UINT8 Option + ); + +/** + Function to display system event log status information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySELLogStatus ( + UINT8 Key, + UINT8 Option + ); + +/** + Function to display system event log header format information. + + @param[in] Key Additional information to print. + @param[in] Option Whether to print the additional information. +**/ +VOID +DisplaySysEventLogHeaderFormat ( + UINT8 Key, + UINT8 Option + ); + +/** + Function to display system event log header information. + + @param[in] LogHeaderFormat Format identifier. + @param[in] LogHeader Format informcation. +**/ +VOID +DisplaySysEventLogHeader ( + UINT8 LogHeaderFormat, + UINT8 *LogHeader + ); + +/** + Function to display system event log data. + + @param[in] LogData The data information. + @param[in] LogAreaLength Length of the data. +**/ +VOID +DisplaySysEventLogData ( + UINT8 *LogData, + UINT16 LogAreaLength + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.c new file mode 100644 index 00000000..f86e6113 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.c @@ -0,0 +1,367 @@ +/** @file + API for SMBIOS table. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include "UefiShellDebug1CommandsLib.h" +#include <Guid/SmBios.h> +#include "LibSmbiosView.h" +#include "SmbiosView.h" + +STATIC UINT8 mInit = 0; +STATIC UINT8 m64Init = 0; +STATIC SMBIOS_TABLE_ENTRY_POINT *mSmbiosTable = NULL; +STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mSmbios64BitTable = NULL; +STATIC SMBIOS_STRUCTURE_POINTER m_SmbiosStruct; +STATIC SMBIOS_STRUCTURE_POINTER *mSmbiosStruct = &m_SmbiosStruct; +STATIC SMBIOS_STRUCTURE_POINTER m_Smbios64BitStruct; +STATIC SMBIOS_STRUCTURE_POINTER *mSmbios64BitStruct = &m_Smbios64BitStruct; + +/** + Init the SMBIOS VIEW API's environment. + + @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. +**/ +EFI_STATUS +LibSmbiosInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Init only once + // + if (mInit == 1) { + return EFI_SUCCESS; + } + // + // Get SMBIOS table from System Configure table + // + Status = GetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID**)&mSmbiosTable); + + if (mSmbiosTable == NULL) { + return EFI_NOT_FOUND; + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status); + return Status; + } + // + // Init SMBIOS structure table address + // + mSmbiosStruct->Raw = (UINT8 *) (UINTN) (mSmbiosTable->TableAddress); + + mInit = 1; + return EFI_SUCCESS; +} + +/** + Init the SMBIOS VIEW API's environment. + + @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. +**/ +EFI_STATUS +LibSmbios64BitInit ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Init only once + // + if (m64Init == 1) { + return EFI_SUCCESS; + } + // + // Get SMBIOS table from System Configure table + // + Status = GetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID**)&mSmbios64BitTable); + + if (mSmbios64BitTable == NULL) { + return EFI_NOT_FOUND; + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status); + return Status; + } + // + // Init SMBIOS structure table address + // + mSmbios64BitStruct->Raw = (UINT8 *) (UINTN) (mSmbios64BitTable->TableAddress); + + m64Init = 1; + return EFI_SUCCESS; +} + +/** + Cleanup the Smbios information. +**/ +VOID +LibSmbiosCleanup ( + VOID + ) +{ + // + // Release resources + // + if (mSmbiosTable != NULL) { + mSmbiosTable = NULL; + } + + mInit = 0; +} + +/** + Cleanup the Smbios information. +**/ +VOID +LibSmbios64BitCleanup ( + VOID + ) +{ + // + // Release resources + // + if (mSmbios64BitTable != NULL) { + mSmbios64BitTable = NULL; + } + + m64Init = 0; +} + +/** + Get the entry point structure for the table. + + @param[out] EntryPointStructure The pointer to populate. +**/ +VOID +LibSmbiosGetEPS ( + OUT SMBIOS_TABLE_ENTRY_POINT **EntryPointStructure + ) +{ + // + // return SMBIOS Table address + // + *EntryPointStructure = mSmbiosTable; +} + +/** + Get the entry point structure for the table. + + @param[out] EntryPointStructure The pointer to populate. +**/ +VOID +LibSmbios64BitGetEPS ( + OUT SMBIOS_TABLE_3_0_ENTRY_POINT **EntryPointStructure + ) +{ + // + // return SMBIOS Table address + // + *EntryPointStructure = mSmbios64BitTable; +} + +/** + Return SMBIOS string for the given string number. + + @param[in] Smbios Pointer to SMBIOS structure. + @param[in] StringNumber String number to return. -1 is used to skip all strings and + point to the next SMBIOS structure. + + @return Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1 +**/ +CHAR8* +LibGetSmbiosString ( + IN SMBIOS_STRUCTURE_POINTER *Smbios, + IN UINT16 StringNumber + ) +{ + UINT16 Index; + CHAR8 *String; + + ASSERT (Smbios != NULL); + + // + // Skip over formatted section + // + String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length); + + // + // Look through unformated section + // + for (Index = 1; Index <= StringNumber; Index++) { + if (StringNumber == Index) { + return String; + } + // + // Skip string + // + for (; *String != 0; String++); + String++; + + if (*String == 0) { + // + // If double NULL then we are done. + // Return pointer to next structure in Smbios. + // if you pass in a -1 you will always get here + // + Smbios->Raw = (UINT8 *)++String; + return NULL; + } + } + + return NULL; +} + +/** + Get SMBIOS structure for the given Handle, + Handle is changed to the next handle or 0xFFFF when the end is + reached or the handle is not found. + + @param[in, out] Handle 0xFFFF: get the first structure + Others: get a structure according to this value. + @param[out] Buffer The pointer to the pointer to the structure. + @param[out] Length Length of the structure. + + @retval DMI_SUCCESS Handle is updated with next structure handle or + 0xFFFF(end-of-list). + + @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or + 0xFFFF(end-of-list). +**/ +EFI_STATUS +LibGetSmbiosStructure ( + IN OUT UINT16 *Handle, + OUT UINT8 **Buffer, + OUT UINT16 *Length + ) +{ + SMBIOS_STRUCTURE_POINTER Smbios; + SMBIOS_STRUCTURE_POINTER SmbiosEnd; + UINT8 *Raw; + + if (*Handle == INVALID_HANDLE) { + *Handle = mSmbiosStruct->Hdr->Handle; + return DMI_INVALID_HANDLE; + } + + if ((Buffer == NULL) || (Length == NULL)) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle); + return DMI_INVALID_HANDLE; + } + + *Length = 0; + Smbios.Hdr = mSmbiosStruct->Hdr; + SmbiosEnd.Raw = Smbios.Raw + mSmbiosTable->TableLength; + while (Smbios.Raw < SmbiosEnd.Raw) { + if (Smbios.Hdr->Handle == *Handle) { + Raw = Smbios.Raw; + // + // Walk to next structure + // + LibGetSmbiosString (&Smbios, (UINT16) (-1)); + // + // Length = Next structure head - this structure head + // + *Length = (UINT16) (Smbios.Raw - Raw); + *Buffer = Raw; + // + // update with the next structure handle. + // + if (Smbios.Raw < SmbiosEnd.Raw) { + *Handle = Smbios.Hdr->Handle; + } else { + *Handle = INVALID_HANDLE; + } + return DMI_SUCCESS; + } + // + // Walk to next structure + // + LibGetSmbiosString (&Smbios, (UINT16) (-1)); + } + + *Handle = INVALID_HANDLE; + return DMI_INVALID_HANDLE; +} + +/** + Get SMBIOS structure for the given Handle, + Handle is changed to the next handle or 0xFFFF when the end is + reached or the handle is not found. + + @param[in, out] Handle 0xFFFF: get the first structure + Others: get a structure according to this value. + @param[out] Buffer The pointer to the pointer to the structure. + @param[out] Length Length of the structure. + + @retval DMI_SUCCESS Handle is updated with next structure handle or + 0xFFFF(end-of-list). + + @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or + 0xFFFF(end-of-list). +**/ +EFI_STATUS +LibGetSmbios64BitStructure ( + IN OUT UINT16 *Handle, + OUT UINT8 **Buffer, + OUT UINT16 *Length + ) +{ + SMBIOS_STRUCTURE_POINTER Smbios; + SMBIOS_STRUCTURE_POINTER SmbiosEnd; + UINT8 *Raw; + + if (*Handle == INVALID_HANDLE) { + *Handle = mSmbios64BitStruct->Hdr->Handle; + return DMI_INVALID_HANDLE; + } + + if ((Buffer == NULL) || (Length == NULL)) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle); + return DMI_INVALID_HANDLE; + } + + *Length = 0; + Smbios.Hdr = mSmbios64BitStruct->Hdr; + + SmbiosEnd.Raw = Smbios.Raw + mSmbios64BitTableLength; + while (Smbios.Raw < SmbiosEnd.Raw) { + if (Smbios.Hdr->Handle == *Handle) { + Raw = Smbios.Raw; + // + // Walk to next structure + // + LibGetSmbiosString (&Smbios, (UINT16) (-1)); + // + // Length = Next structure head - this structure head + // + *Length = (UINT16) (Smbios.Raw - Raw); + *Buffer = Raw; + // + // update with the next structure handle. + // + if (Smbios.Raw < SmbiosEnd.Raw) { + *Handle = Smbios.Hdr->Handle; + } else { + *Handle = INVALID_HANDLE; + } + return DMI_SUCCESS; + } + // + // Walk to next structure + // + LibGetSmbiosString (&Smbios, (UINT16) (-1)); + } + + *Handle = INVALID_HANDLE; + return DMI_INVALID_HANDLE; +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.h new file mode 100644 index 00000000..d7f43c9d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/LibSmbiosView.h @@ -0,0 +1,153 @@ +/** @file + API for SMBIOS Plug and Play functions, access to SMBIOS table and structures. + + Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _LIB_SMBIOS_VIEW_H_ +#define _LIB_SMBIOS_VIEW_H_ + +#include <IndustryStandard/SmBios.h> + +#define DMI_SUCCESS 0x00 +#define DMI_UNKNOWN_FUNCTION 0x81 +#define DMI_FUNCTION_NOT_SUPPORTED 0x82 +#define DMI_INVALID_HANDLE 0x83 +#define DMI_BAD_PARAMETER 0x84 +#define DMI_INVALID_SUBFUNCTION 0x85 +#define DMI_NO_CHANGE 0x86 +#define DMI_ADD_STRUCTURE_FAILED 0x87 +#define DMI_READ_ONLY 0x8D +#define DMI_LOCK_NOT_SUPPORTED 0x90 +#define DMI_CURRENTLY_LOCKED 0x91 +#define DMI_INVALID_LOCK 0x92 + +#define INVALID_HANDLE (UINT16) (-1) + +#define EFI_SMBIOSERR(val) EFIERR (0x30000 | val) + +#define EFI_SMBIOSERR_FAILURE EFI_SMBIOSERR (1) +#define EFI_SMBIOSERR_STRUCT_NOT_FOUND EFI_SMBIOSERR (2) +#define EFI_SMBIOSERR_TYPE_UNKNOWN EFI_SMBIOSERR (3) +#define EFI_SMBIOSERR_UNSUPPORTED EFI_SMBIOSERR (4) + +/** + Init the SMBIOS VIEW API's environment for the 32-bit table.. + + @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. +**/ +EFI_STATUS +LibSmbiosInit ( + VOID + ); + +/** + Init the SMBIOS VIEW API's environment for the 64-bit table.. + + @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. +**/ +EFI_STATUS +LibSmbios64BitInit ( + VOID + ); + +/** + Cleanup the Smbios information. +**/ +VOID +LibSmbiosCleanup ( + VOID + ); + +/** + Cleanup the Smbios information. +**/ +VOID +LibSmbios64BitCleanup ( + VOID + ); + +/** + Get the entry point structure for the table. + + @param[out] EntryPointStructure The pointer to populate. +**/ +VOID +LibSmbiosGetEPS ( + OUT SMBIOS_TABLE_ENTRY_POINT **EntryPointStructure + ); + +/** + Get the entry point structure for the 64-bit table. + + @param[out] EntryPointStructure The pointer to populate. +**/ +VOID +LibSmbios64BitGetEPS ( + OUT SMBIOS_TABLE_3_0_ENTRY_POINT **EntryPointStructure + ); + +/** + Return SMBIOS string for the given string number. + + @param[in] Smbios Pointer to SMBIOS structure. + @param[in] StringNumber String number to return. -1 is used to skip all strings and + point to the next SMBIOS structure. + + @return Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1 +**/ +CHAR8* +LibGetSmbiosString ( + IN SMBIOS_STRUCTURE_POINTER *Smbios, + IN UINT16 StringNumber + ); + +/** + Get SMBIOS structure for the given Handle, + Handle is changed to the next handle or 0xFFFF when the end is + reached or the handle is not found. + + @param[in, out] Handle 0xFFFF: get the first structure + Others: get a structure according to this value. + @param[out] Buffer The pointer to the pointer to the structure. + @param[out] Length Length of the structure. + + @retval DMI_SUCCESS Handle is updated with next structure handle or + 0xFFFF(end-of-list). + + @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or + 0xFFFF(end-of-list). +**/ +EFI_STATUS +LibGetSmbiosStructure ( + IN OUT UINT16 *Handle, + OUT UINT8 **Buffer, + OUT UINT16 *Length + ); + +/** + Get SMBIOS structure for the given Handle in 64-bit table, + Handle is changed to the next handle or 0xFFFF when the end is + reached or the handle is not found. + + @param[in, out] Handle 0xFFFF: get the first structure + Others: get a structure according to this value. + @param[out] Buffer The pointer to the pointer to the structure. + @param[out] Length Length of the structure. + + @retval DMI_SUCCESS Handle is updated with next structure handle or + 0xFFFF(end-of-list). + + @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or + 0xFFFF(end-of-list). +**/ +EFI_STATUS +LibGetSmbios64BitStructure ( + IN OUT UINT16 *Handle, + OUT UINT8 **Buffer, + OUT UINT16 *Length + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c new file mode 100644 index 00000000..a89688c8 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c @@ -0,0 +1,3456 @@ +/** @file + Module for clarifying the content of the smbios structure element information. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR> + (C) Copyright 2015-2019 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "PrintInfo.h" +#include "LibSmbiosView.h" +#include "QueryTable.h" +#include "EventLogInfo.h" + + +// +// Get the certain bit of 'value' +// +#define BIT(value, bit) ((value) & ((UINT64) 1) << (bit)) + +// +// Check if above or equal to version +// +#define AE_SMBIOS_VERSION(MajorVersion, MinorVersion) \ + (SmbiosMajorVersion > (MajorVersion) || (SmbiosMajorVersion == (MajorVersion) && SmbiosMinorVersion >= (MinorVersion))) + +// +////////////////////////////////////////////////////////// +// Macros of print structure element, simplify coding. +// +#define PRINT_PENDING_STRING(pStruct, type, element) \ + do { \ + CHAR8 *StringBuf; \ + StringBuf = LibGetSmbiosString ((pStruct), (pStruct->type->element)); \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintEx(-1,-1,L": %a\n", (StringBuf != NULL) ? StringBuf: ""); \ + } while (0); + +#define PRINT_SMBIOS_STRING(pStruct, stringnumber, element) \ + do { \ + CHAR8 *StringBuf; \ + StringBuf = LibGetSmbiosString ((pStruct), (stringnumber)); \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintEx(-1,-1,L": %a\n", (StringBuf != NULL) ? StringBuf: ""); \ + } while (0); + +#define PRINT_STRUCT_VALUE(pStruct, type, element) \ + do { \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintEx(-1,-1,L": %u\n", (pStruct->type->element)); \ + } while (0); + +#define PRINT_STRUCT_VALUE_H(pStruct, type, element) \ + do { \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintEx(-1,-1,L": 0x%x\n", (pStruct->type->element)); \ + } while (0); + +#define PRINT_STRUCT_VALUE_LH(pStruct, type, element) \ + do { \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintEx(-1,-1,L": 0x%lx\n", (pStruct->type->element)); \ + } while (0); + +#define PRINT_BIT_FIELD(pStruct, type, element, size) \ + do { \ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DUMP), gShellDebug1HiiHandle); \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SIZE), gShellDebug1HiiHandle, size); \ + DumpHex (0, 0, size, &(pStruct->type->element)); \ + } while (0); + +#define PRINT_SMBIOS_BIT_FIELD(pStruct, startaddress, element, size) \ + do { \ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DUMP), gShellDebug1HiiHandle); \ + ShellPrintEx(-1,-1,L"%a",#element); \ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SIZE), gShellDebug1HiiHandle, size); \ + DumpHex (0, 0, size, startaddress); \ + } while (0); + +// +///////////////////////////////////////// +// + +/** + Copy Length of Src buffer to Dest buffer, + add a NULL termination to Dest buffer. + + @param[in, out] Dest Destination buffer head. + @param[in] Src Source buffer head. + @param[in] Length Length of buffer to be copied. +**/ +VOID +MemToString ( + IN OUT VOID *Dest, + IN VOID *Src, + IN UINTN Length + ) +{ + UINT8 *SrcBuffer; + UINT8 *DestBuffer; + SrcBuffer = (UINT8 *) Src; + DestBuffer = (UINT8 *) Dest; + // + // copy byte by byte + // + while ((Length--)!=0) { + *DestBuffer++ = *SrcBuffer++; + } + // + // append a NULL terminator + // + *DestBuffer = '\0'; +} + +// +////////////////////////////////////////////// +// +// Functions below is to show the information +// + +/** + Print the info of EPS(Entry Point Structure). + + @param[in] SmbiosTable Pointer to the SMBIOS table entry point. + @param[in] Option Display option. +**/ +VOID +SmbiosPrintEPSInfo ( + IN SMBIOS_TABLE_ENTRY_POINT *SmbiosTable, + IN UINT8 Option + ) +{ + UINT8 Anchor[5]; + UINT8 InAnchor[6]; + + if (SmbiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SMBIOSTABLE_NULL), gShellDebug1HiiHandle); + return ; + } + + if (Option == SHOW_NONE) { + return ; + } + + if (Option >= SHOW_NORMAL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_SIGN), gShellDebug1HiiHandle); + MemToString (Anchor, SmbiosTable->AnchorString, 4); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ANCHOR_STR), gShellDebug1HiiHandle, Anchor); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EPS_CHECKSUM), + gShellDebug1HiiHandle, + SmbiosTable->EntryPointStructureChecksum + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_LEN), gShellDebug1HiiHandle, SmbiosTable->EntryPointLength); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VERSION), + gShellDebug1HiiHandle, + SmbiosTable->MajorVersion, + SmbiosTable->MinorVersion + ); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NUMBER_STRUCT), + gShellDebug1HiiHandle, + SmbiosTable->NumberOfSmbiosStructures + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MAX_STRUCT_SIZE), gShellDebug1HiiHandle, SmbiosTable->MaxStructureSize); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TABLE_ADDR), gShellDebug1HiiHandle, SmbiosTable->TableAddress); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TABLE_LENGTH), gShellDebug1HiiHandle, SmbiosTable->TableLength); + + } + // + // If SHOW_ALL, also print followings. + // + if (Option >= SHOW_DETAIL) { + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_REVISION), + gShellDebug1HiiHandle, + SmbiosTable->EntryPointRevision + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BCD_REVISION), gShellDebug1HiiHandle, SmbiosTable->SmbiosBcdRevision); + // + // Since raw data is not string, add a NULL terminater. + // + MemToString (InAnchor, SmbiosTable->IntermediateAnchorString, 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTER_ACHOR), gShellDebug1HiiHandle, InAnchor); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTER_CHECKSUM), gShellDebug1HiiHandle, SmbiosTable->IntermediateChecksum); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FORMATTED_AREA), gShellDebug1HiiHandle); + DumpHex (2, 0, 5, SmbiosTable->FormattedArea); + } + + Print (L"\n"); +} + +/** + Print the info of 64-bit EPS(Entry Point Structure). + + @param[in] SmbiosTable Pointer to the SMBIOS table entry point. + @param[in] Option Display option. +**/ +VOID +Smbios64BitPrintEPSInfo ( + IN SMBIOS_TABLE_3_0_ENTRY_POINT *SmbiosTable, + IN UINT8 Option + ) +{ + UINT8 Anchor[5]; + + if (SmbiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SMBIOSTABLE_NULL), gShellDebug1HiiHandle); + return ; + } + + if (Option == SHOW_NONE) { + return ; + } + + if (Option >= SHOW_NORMAL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_64_BIT_ENTRY_POINT_SIGN), gShellDebug1HiiHandle); + + MemToString (Anchor, SmbiosTable->AnchorString, 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ANCHOR_STR), gShellDebug1HiiHandle, Anchor); + + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EPS_CHECKSUM), + gShellDebug1HiiHandle, + SmbiosTable->EntryPointStructureChecksum + ); + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_LEN), gShellDebug1HiiHandle, SmbiosTable->EntryPointLength); + + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VERSION), + gShellDebug1HiiHandle, + SmbiosTable->MajorVersion, + SmbiosTable->MinorVersion + ); + + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DOCREV), + gShellDebug1HiiHandle, + SmbiosTable->DocRev + ); + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TABLE_MAX_SIZE), gShellDebug1HiiHandle, SmbiosTable->TableMaximumSize); + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TABLE_ADDR), gShellDebug1HiiHandle, SmbiosTable->TableAddress); + + } + // + // If SHOW_ALL, also print followings. + // + if (Option >= SHOW_DETAIL) { + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_REVISION), + gShellDebug1HiiHandle, + SmbiosTable->EntryPointRevision + ); + } + + Print (L"\n"); +} + +/** + This function print the content of the structure pointed by Struct. + + @param[in] Struct Point to the structure to be printed. + @param[in] Option Print option of information detail. + + @retval EFI_SUCCESS Successfully Printing this function. + @retval EFI_INVALID_PARAMETER Invalid Structure. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +SmbiosPrintStructure ( + IN SMBIOS_STRUCTURE_POINTER *Struct, + IN UINT8 Option + ) +{ + UINT8 Index; + UINT8 Index2; + UINT8 *Buffer; + + if (Struct == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Option == SHOW_NONE) { + return EFI_SUCCESS; + } + + Buffer = (UINT8 *) (UINTN) (Struct->Raw); + + // + // Display structure header + // + DisplayStructureTypeInfo (Struct->Hdr->Type, SHOW_DETAIL); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FORMAT_PART_LEN), gShellDebug1HiiHandle, Struct->Hdr->Length); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_STRUCT_HANDLE), gShellDebug1HiiHandle, Struct->Hdr->Handle); + + if (Option == SHOW_OUTLINE) { + return EFI_SUCCESS; + } + + switch (Struct->Hdr->Type) { + // + // BIOS Information (Type 0) + // + case 0: + PRINT_PENDING_STRING (Struct, Type0, Vendor); + PRINT_PENDING_STRING (Struct, Type0, BiosVersion); + PRINT_STRUCT_VALUE_H (Struct, Type0, BiosSegment); + PRINT_PENDING_STRING (Struct, Type0, BiosReleaseDate); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_SIZE), gShellDebug1HiiHandle, 64 * (Struct->Type0->BiosSize + 1)); + + DisplayBiosCharacteristics (ReadUnaligned64 ((UINT64 *) (UINTN) &(Struct->Type0->BiosCharacteristics)), Option); + + if (Struct->Hdr->Length > 0x12) { + DisplayBiosCharacteristicsExt1 (Struct->Type0->BIOSCharacteristicsExtensionBytes[0], Option); + } + if (Struct->Hdr->Length > 0x13) { + DisplayBiosCharacteristicsExt2 (Struct->Type0->BIOSCharacteristicsExtensionBytes[1], Option); + } + + if (AE_SMBIOS_VERSION (0x2, 0x4) && (Struct->Hdr->Length > 0x14)) { + PRINT_STRUCT_VALUE (Struct, Type0, SystemBiosMajorRelease); + PRINT_STRUCT_VALUE (Struct, Type0, SystemBiosMinorRelease); + PRINT_STRUCT_VALUE (Struct, Type0, EmbeddedControllerFirmwareMajorRelease); + PRINT_STRUCT_VALUE (Struct, Type0, EmbeddedControllerFirmwareMinorRelease); + } + if (AE_SMBIOS_VERSION (0x3, 0x1) && (Struct->Hdr->Length > 0x18)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EXTENDED_BIOS_SIZE), + gShellDebug1HiiHandle, + Struct->Type0->ExtendedBiosSize.Size, + (Struct->Type0->ExtendedBiosSize.Unit == 0x0) ? L"MB": L"GB" + ); + } + break; + + // + // System Information (Type 1) + // + case 1: + PRINT_PENDING_STRING (Struct, Type1, Manufacturer); + PRINT_PENDING_STRING (Struct, Type1, ProductName); + PRINT_PENDING_STRING (Struct, Type1, Version); + PRINT_PENDING_STRING (Struct, Type1, SerialNumber); + PRINT_BIT_FIELD (Struct, Type1, Uuid, 16); + DisplaySystemWakeupType (Struct->Type1->WakeUpType, Option); + if (AE_SMBIOS_VERSION (0x2, 0x4) && (Struct->Hdr->Length > 0x19)) { + PRINT_PENDING_STRING (Struct, Type1, SKUNumber); + PRINT_PENDING_STRING (Struct, Type1, Family); + } + + break; + + // + // Baseboard Information (Type 2) + // + case 2: + PRINT_PENDING_STRING (Struct, Type2, Manufacturer); + PRINT_PENDING_STRING (Struct, Type2, ProductName); + PRINT_PENDING_STRING (Struct, Type2, Version); + PRINT_PENDING_STRING (Struct, Type2, SerialNumber); + if (Struct->Hdr->Length > 0x8) { + PRINT_PENDING_STRING (Struct, Type2, AssetTag); + DisplayBaseBoardFeatureFlags (*(UINT8 *) &Struct->Type2->FeatureFlag, Option); + PRINT_PENDING_STRING (Struct, Type2, LocationInChassis); + PRINT_STRUCT_VALUE_H (Struct, Type2, ChassisHandle); + DisplayBaseBoardBoardType (Struct->Type2->BoardType, Option); + } + break; + + // + // System Enclosure (Type 3) + // + case 3: + PRINT_PENDING_STRING (Struct, Type3, Manufacturer); + PRINT_STRUCT_VALUE (Struct, Type3, Type); + DisplaySystemEnclosureType (Struct->Type3->Type, Option); + PRINT_PENDING_STRING (Struct, Type3, Version); + PRINT_PENDING_STRING (Struct, Type3, SerialNumber); + PRINT_PENDING_STRING (Struct, Type3, AssetTag); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BOOTUP_STATE), gShellDebug1HiiHandle); + DisplaySystemEnclosureStatus (Struct->Type3->BootupState, Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_STATE), gShellDebug1HiiHandle); + DisplaySystemEnclosureStatus (Struct->Type3->PowerSupplyState, Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_THERMAL_STATE), gShellDebug1HiiHandle); + DisplaySystemEnclosureStatus (Struct->Type3->ThermalState, Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SECURITY_STATUS), gShellDebug1HiiHandle); + DisplaySESecurityStatus (Struct->Type3->SecurityStatus, Option); + if (AE_SMBIOS_VERSION (0x2, 0x3)) { + if (Struct->Hdr->Length > 0xD) { + PRINT_BIT_FIELD (Struct, Type3, OemDefined, 4); + } + if (Struct->Hdr->Length > 0x11) { + PRINT_STRUCT_VALUE (Struct, Type3, Height); + } + if (Struct->Hdr->Length > 0x12) { + PRINT_STRUCT_VALUE (Struct, Type3, NumberofPowerCords); + } + if (Struct->Hdr->Length > 0x13) { + PRINT_STRUCT_VALUE (Struct, Type3, ContainedElementCount); + } + if (Struct->Hdr->Length > 0x14) { + PRINT_STRUCT_VALUE (Struct, Type3, ContainedElementRecordLength); + } + if (Struct->Hdr->Length > 0x15) { + for (Index = 0; Index < Struct->Type3->ContainedElementCount; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CONTAINED_ELEMENT), gShellDebug1HiiHandle, Index+1); + for (Index2 = 0; Index2< Struct->Type3->ContainedElementRecordLength; Index2++) { + Print (L"%02X ", Buffer[0x15 + (Index * Struct->Type3->ContainedElementRecordLength) + Index2]); + } + Print (L"\n"); + } + } + } + if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0x13)) { + if (Struct->Hdr->Length > (0x15 + (Struct->Type3->ContainedElementCount * Struct->Type3->ContainedElementRecordLength))) { + PRINT_SMBIOS_STRING (Struct, Buffer[0x15 + (Struct->Type3->ContainedElementCount * Struct->Type3->ContainedElementRecordLength)], SKUNumber); + } + } + break; + + // + // Processor Information (Type 4) + // + case 4: + PRINT_SMBIOS_STRING (Struct, Struct->Type4->Socket, SocketDesignation) + DisplayProcessorType (Struct->Type4->ProcessorType, Option); + if (AE_SMBIOS_VERSION (0x2, 0x6) && (Struct->Hdr->Length > 0x28) && + (Struct->Type4->ProcessorFamily == 0xFE)) { + // + // Get family from ProcessorFamily2 field + // + DisplayProcessorFamily2 (Struct->Type4->ProcessorFamily2, Option); + } else { + DisplayProcessorFamily (Struct->Type4->ProcessorFamily, Option); + } + PRINT_PENDING_STRING (Struct, Type4, ProcessorManufacturer); + PRINT_BIT_FIELD (Struct, Type4, ProcessorId, 8); + PRINT_PENDING_STRING (Struct, Type4, ProcessorVersion); + DisplayProcessorVoltage (*(UINT8 *) &(Struct->Type4->Voltage), Option); + PRINT_STRUCT_VALUE (Struct, Type4, ExternalClock); + PRINT_STRUCT_VALUE (Struct, Type4, MaxSpeed); + PRINT_STRUCT_VALUE (Struct, Type4, CurrentSpeed); + DisplayProcessorStatus (Struct->Type4->Status, Option); + DisplayProcessorUpgrade (Struct->Type4->ProcessorUpgrade, Option); + PRINT_STRUCT_VALUE_H (Struct, Type4, L1CacheHandle); + PRINT_STRUCT_VALUE_H (Struct, Type4, L2CacheHandle); + PRINT_STRUCT_VALUE_H (Struct, Type4, L3CacheHandle); + if (AE_SMBIOS_VERSION (0x2, 0x3) && (Struct->Hdr->Length > 0x20)) { + PRINT_PENDING_STRING (Struct, Type4, SerialNumber); + PRINT_PENDING_STRING (Struct, Type4, AssetTag); + PRINT_PENDING_STRING (Struct, Type4, PartNumber); + } + if (AE_SMBIOS_VERSION (0x2, 0x5) && (Struct->Hdr->Length > 0x23)) { + PRINT_STRUCT_VALUE (Struct, Type4, CoreCount); + PRINT_STRUCT_VALUE (Struct, Type4, EnabledCoreCount); + PRINT_STRUCT_VALUE (Struct, Type4, ThreadCount); + DisplayProcessorCharacteristics (Struct->Type4->ProcessorCharacteristics, Option); + } + if ((SmbiosMajorVersion >= 0x3) && (Struct->Hdr->Length > 0x2A)) { + PRINT_STRUCT_VALUE (Struct, Type4, CoreCount2); + PRINT_STRUCT_VALUE (Struct, Type4, EnabledCoreCount2); + PRINT_STRUCT_VALUE (Struct, Type4, ThreadCount2); + } + break; + + // + // Memory Controller Information (Type 5) + // + case 5: + { + UINT8 SlotNum; + SlotNum = Struct->Type5->AssociatedMemorySlotNum; + + DisplayMcErrorDetectMethod (Struct->Type5->ErrDetectMethod, Option); + DisplayMcErrorCorrectCapability (*(UINT8 *) &(Struct->Type5->ErrCorrectCapability), Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SUPOPRT), gShellDebug1HiiHandle); + DisplayMcInterleaveSupport (Struct->Type5->SupportInterleave, Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CURRENT), gShellDebug1HiiHandle); + DisplayMcInterleaveSupport (Struct->Type5->CurrentInterleave, Option); + DisplayMaxMemoryModuleSize (Struct->Type5->MaxMemoryModuleSize, SlotNum, Option); + DisplayMcMemorySpeeds (*(UINT16 *) &(Struct->Type5->SupportSpeed), Option); + DisplayMmMemoryType (Struct->Type5->SupportMemoryType, Option); + DisplayMemoryModuleVoltage (Struct->Type5->MemoryModuleVoltage, Option); + PRINT_STRUCT_VALUE (Struct, Type5, AssociatedMemorySlotNum); + // + // According to SMBIOS Specification, offset 0x0F + // + DisplayMemoryModuleConfigHandles ((UINT16 *) (&Buffer[0x0F]), SlotNum, Option); + DisplayMcErrorCorrectCapability (Buffer[0x0F + 2 * SlotNum], Option); + } + break; + + // + // Memory Module Information (Type 6) + // + case 6: + PRINT_PENDING_STRING (Struct, Type6, SocketDesignation); + DisplayMmBankConnections (Struct->Type6->BankConnections, Option); + PRINT_STRUCT_VALUE (Struct, Type6, CurrentSpeed); + DisplayMmMemoryType (*(UINT16 *) &(Struct->Type6->CurrentMemoryType), Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INSTALLED), gShellDebug1HiiHandle); + DisplayMmMemorySize (*(UINT8 *) &(Struct->Type6->InstalledSize), Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED), gShellDebug1HiiHandle); + DisplayMmMemorySize (*(UINT8 *) &(Struct->Type6->EnabledSize), Option); + DisplayMmErrorStatus (Struct->Type6->ErrorStatus, Option); + break; + + // + // Cache Information (Type 7) + // + case 7: + PRINT_PENDING_STRING (Struct, Type7, SocketDesignation); + DisplayCacheConfiguration (Struct->Type7->CacheConfiguration, Option); + PRINT_STRUCT_VALUE_H (Struct, Type7, MaximumCacheSize); + PRINT_STRUCT_VALUE_H (Struct, Type7, InstalledSize); + PRINT_STRUCT_VALUE_H (Struct, Type7, SupportedSRAMType); + PRINT_STRUCT_VALUE_H (Struct, Type7, CurrentSRAMType); + DisplayCacheSRAMType (ReadUnaligned16 ((UINT16 *) (UINTN) &(Struct->Type7->CurrentSRAMType)), Option); + PRINT_STRUCT_VALUE_H (Struct, Type7, CacheSpeed); + DisplayCacheErrCorrectingType (Struct->Type7->ErrorCorrectionType, Option); + DisplayCacheSystemCacheType (Struct->Type7->SystemCacheType, Option); + DisplayCacheAssociativity (Struct->Type7->Associativity, Option); + if (AE_SMBIOS_VERSION (0x3, 0x1) && (Struct->Hdr->Length > 0x13)) { + PRINT_STRUCT_VALUE_H (Struct, Type7, MaximumCacheSize2); + PRINT_STRUCT_VALUE_H (Struct, Type7, InstalledSize2); + } + break; + + // + // Port Connector Information (Type 8) + // + case 8: + PRINT_PENDING_STRING (Struct, Type8, InternalReferenceDesignator); + Print (L"Internal "); + DisplayPortConnectorType (Struct->Type8->InternalConnectorType, Option); + PRINT_PENDING_STRING (Struct, Type8, ExternalReferenceDesignator); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EXTERNAL), gShellDebug1HiiHandle); + DisplayPortConnectorType (Struct->Type8->ExternalConnectorType, Option); + DisplayPortType (Struct->Type8->PortType, Option); + break; + + // + // System Slots (Type 9) + // + case 9: + { + MISC_SLOT_PEER_GROUP *PeerGroupPtr; + UINT8 PeerGroupCount; + + PRINT_PENDING_STRING (Struct, Type9, SlotDesignation); + DisplaySystemSlotType (Struct->Type9->SlotType, Option); + DisplaySystemSlotDataBusWidth (Struct->Type9->SlotDataBusWidth, Option); + DisplaySystemSlotCurrentUsage (Struct->Type9->CurrentUsage, Option); + DisplaySystemSlotLength (Struct->Type9->SlotLength, Option); + DisplaySystemSlotId ( + Struct->Type9->SlotID, + Struct->Type9->SlotType, + Option + ); + DisplaySlotCharacteristics1 (*(UINT8 *) &(Struct->Type9->SlotCharacteristics1), Option); + DisplaySlotCharacteristics2 (*(UINT8 *) &(Struct->Type9->SlotCharacteristics2), Option); + if (AE_SMBIOS_VERSION (0x2, 0x6) && (Struct->Hdr->Length > 0xD)) { + PRINT_STRUCT_VALUE_H (Struct, Type9, SegmentGroupNum); + PRINT_STRUCT_VALUE_H (Struct, Type9, BusNum); + PRINT_STRUCT_VALUE_H (Struct, Type9, DevFuncNum); + } + if (AE_SMBIOS_VERSION (0x3, 0x2)) { + if (Struct->Hdr->Length > 0x11) { + PRINT_STRUCT_VALUE (Struct, Type9, DataBusWidth); + } + if (Struct->Hdr->Length > 0x12) { + PRINT_STRUCT_VALUE (Struct, Type9, PeerGroupingCount); + + PeerGroupCount = Struct->Type9->PeerGroupingCount; + PeerGroupPtr = Struct->Type9->PeerGroups; + for (Index = 0; Index < PeerGroupCount; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SLOT_PEER_GROUPS), gShellDebug1HiiHandle, Index + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SEGMENT_GROUP_NUM), gShellDebug1HiiHandle, PeerGroupPtr[Index].SegmentGroupNum); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BUS_NUM), gShellDebug1HiiHandle, PeerGroupPtr[Index].BusNum); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DEV_FUNC_NUM), gShellDebug1HiiHandle, PeerGroupPtr[Index].DevFuncNum); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DATA_BUS_WIDTH), gShellDebug1HiiHandle, PeerGroupPtr[Index].DataBusWidth); + } + } + } + } + break; + + // + // On Board Devices Information (Type 10) + // + case 10: + { + UINTN NumOfDevice; + NumOfDevice = (Struct->Type10->Hdr.Length - sizeof (SMBIOS_STRUCTURE)) / (2 * sizeof (UINT8)); + for (Index = 0; Index < NumOfDevice; Index++) { + ShellPrintEx(-1,-1,(((Struct->Type10->Device[Index].DeviceType) & 0x80) != 0) ? L"Device Enabled\n": L"Device Disabled\n"); + DisplayOnboardDeviceTypes ((Struct->Type10->Device[Index].DeviceType) & 0x7F, Option); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DESC_STRING), gShellDebug1HiiHandle); + ShellPrintEx(-1,-1,L"%a\n",LibGetSmbiosString (Struct, Struct->Type10->Device[Index].DescriptionString)); + } + } + break; + + // + // Oem Strings (Type 11) + // + case 11: + PRINT_STRUCT_VALUE (Struct, Type11, StringCount); + for (Index = 1; Index <= Struct->Type11->StringCount; Index++) { + ShellPrintEx(-1,-1,L"%a\n", LibGetSmbiosString (Struct, Index)); + } + break; + + // + // System Configuration Options (Type 12) + // + case 12: + PRINT_STRUCT_VALUE (Struct, Type12, StringCount); + for (Index = 1; Index <= Struct->Type12->StringCount; Index++) { + ShellPrintEx(-1,-1,L"%a\n", LibGetSmbiosString (Struct, Index)); + } + break; + + // + // BIOS Language Information (Type 13) + // + case 13: + PRINT_STRUCT_VALUE (Struct, Type13, InstallableLanguages); + PRINT_STRUCT_VALUE (Struct, Type13, Flags); + PRINT_BIT_FIELD (Struct, Type13, Reserved, 15); + PRINT_PENDING_STRING (Struct, Type13, CurrentLanguages); + break; + + // + // Group Associations (Type 14) + // + case 14: + { + UINT8 NumOfItem; + NumOfItem = (Struct->Type14->Hdr.Length - 5) / 3; + PRINT_PENDING_STRING (Struct, Type14, GroupName); + for (Index = 0; Index < NumOfItem; Index++) { + ShellPrintEx(-1,-1,L"ItemType %u: %u\n", Index + 1, Struct->Type14->Group[Index].ItemType); + ShellPrintEx(-1,-1,L"ItemHandle %u: %u\n", Index + 1, Struct->Type14->Group[Index].ItemHandle); + } + } + break; + + // + // System Event Log (Type 15) + // + case 15: + { + EVENT_LOG_TYPE *Ptr; + UINT8 Count; + UINT8 *AccessMethodAddress; + + PRINT_STRUCT_VALUE_H (Struct, Type15, LogAreaLength); + PRINT_STRUCT_VALUE_H (Struct, Type15, LogHeaderStartOffset); + PRINT_STRUCT_VALUE_H (Struct, Type15, LogDataStartOffset); + DisplaySELAccessMethod (Struct->Type15->AccessMethod, Option); + PRINT_STRUCT_VALUE_H (Struct, Type15, AccessMethodAddress); + DisplaySELLogStatus (Struct->Type15->LogStatus, Option); + PRINT_STRUCT_VALUE_H (Struct, Type15, LogChangeToken); + DisplaySysEventLogHeaderFormat (Struct->Type15->LogHeaderFormat, Option); + PRINT_STRUCT_VALUE_H (Struct, Type15, NumberOfSupportedLogTypeDescriptors); + PRINT_STRUCT_VALUE_H (Struct, Type15, LengthOfLogTypeDescriptor); + + Count = Struct->Type15->NumberOfSupportedLogTypeDescriptors; + if (Count > 0) { + Ptr = Struct->Type15->EventLogTypeDescriptors; + + // + // Display all Event Log type descriptors supported by system + // + for (Index = 0; Index < Count; Index++, Ptr++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SUPOPRTED_EVENT), gShellDebug1HiiHandle, Index + 1); + DisplaySELTypes (Ptr->LogType, Option); + DisplaySELVarDataFormatType (Ptr->DataFormatType, Option); + } + + if (Option >= SHOW_DETAIL) { + switch (Struct->Type15->AccessMethod) { + case 03: + AccessMethodAddress = (UINT8 *) (UINTN) (Struct->Type15->AccessMethodAddress); + break; + + case 00: + case 01: + case 02: + case 04: + default: + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ACCESS_METHOD_NOT_SUPOPRTED), + gShellDebug1HiiHandle, + Struct->Type15->AccessMethod + ); + return EFI_UNSUPPORTED; + } + // + // Display Event Log Header + // + // Starting offset (or index) within the nonvolatile storage + // of the event-log's header, from the Access Method Address + // + DisplaySysEventLogHeader ( + Struct->Type15->LogHeaderFormat, + AccessMethodAddress + Struct->Type15->LogHeaderStartOffset + ); + + // + // Display all Event Log data + // + // Starting offset (or index) within the nonvolatile storage + // of the event-log's first data byte, from the Access Method Address(0x14) + // + DisplaySysEventLogData ( + AccessMethodAddress + Struct->Type15->LogDataStartOffset, + (UINT16) + ( + Struct->Type15->LogAreaLength - + (Struct->Type15->LogDataStartOffset - Struct->Type15->LogHeaderStartOffset) + ) + ); + } + + } + } + break; + + // + // Physical Memory Array (Type 16) + // + case 16: + DisplayPMALocation (Struct->Type16->Location, Option); + DisplayPMAUse (Struct->Type16->Use, Option); + DisplayPMAErrorCorrectionTypes ( + Struct->Type16->MemoryErrorCorrection, + Option + ); + PRINT_STRUCT_VALUE_H (Struct, Type16, MaximumCapacity); + PRINT_STRUCT_VALUE_H (Struct, Type16, MemoryErrorInformationHandle); + PRINT_STRUCT_VALUE_H (Struct, Type16, NumberOfMemoryDevices); + if (AE_SMBIOS_VERSION (0x2, 0x7) && Struct->Hdr->Length > 0xF) { + PRINT_STRUCT_VALUE_LH (Struct, Type16, ExtendedMaximumCapacity); + } + break; + + // + // Memory Device (Type 17) + // + case 17: + PRINT_STRUCT_VALUE_H (Struct, Type17, MemoryArrayHandle); + PRINT_STRUCT_VALUE_H (Struct, Type17, MemoryErrorInformationHandle); + PRINT_STRUCT_VALUE_H (Struct, Type17, TotalWidth); + PRINT_STRUCT_VALUE_H (Struct, Type17, DataWidth); + PRINT_STRUCT_VALUE (Struct, Type17, Size); + DisplayMemoryDeviceFormFactor (Struct->Type17->FormFactor, Option); + PRINT_STRUCT_VALUE_H (Struct, Type17, DeviceSet); + PRINT_PENDING_STRING (Struct, Type17, DeviceLocator); + PRINT_PENDING_STRING (Struct, Type17, BankLocator); + DisplayMemoryDeviceType (Struct->Type17->MemoryType, Option); + DisplayMemoryDeviceTypeDetail (ReadUnaligned16 ((UINT16 *) (UINTN) &(Struct->Type17->TypeDetail)), Option); + PRINT_STRUCT_VALUE_H (Struct, Type17, Speed); + PRINT_PENDING_STRING (Struct, Type17, Manufacturer); + PRINT_PENDING_STRING (Struct, Type17, SerialNumber); + PRINT_PENDING_STRING (Struct, Type17, AssetTag); + PRINT_PENDING_STRING (Struct, Type17, PartNumber); + if (AE_SMBIOS_VERSION (0x2, 0x6) && (Struct->Hdr->Length > 0x1B)) { + PRINT_STRUCT_VALUE_H (Struct, Type17, Attributes); + } + if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0x1C)) { + PRINT_STRUCT_VALUE (Struct, Type17, ExtendedSize); + PRINT_STRUCT_VALUE_H (Struct, Type17, ConfiguredMemoryClockSpeed); + } + if (AE_SMBIOS_VERSION (0x2, 0x8) && (Struct->Hdr->Length > 0x22)) { + PRINT_STRUCT_VALUE (Struct, Type17, MinimumVoltage); + PRINT_STRUCT_VALUE (Struct, Type17, MaximumVoltage); + PRINT_STRUCT_VALUE (Struct, Type17, ConfiguredVoltage); + } + if (AE_SMBIOS_VERSION (0x3, 0x2)) { + if (Struct->Hdr->Length > 0x28) { + DisplayMemoryDeviceMemoryTechnology (Struct->Type17->MemoryTechnology, Option); + DisplayMemoryDeviceMemoryOperatingModeCapability (Struct->Type17->MemoryOperatingModeCapability.Uint16, Option); + PRINT_PENDING_STRING (Struct, Type17, FirmwareVersion); + PRINT_STRUCT_VALUE_H (Struct, Type17, ModuleManufacturerID); + PRINT_STRUCT_VALUE_H (Struct, Type17, ModuleProductID); + PRINT_STRUCT_VALUE_H (Struct, Type17, MemorySubsystemControllerManufacturerID); + PRINT_STRUCT_VALUE_H (Struct, Type17, MemorySubsystemControllerProductID); + } + if (Struct->Hdr->Length > 0x34) { + PRINT_STRUCT_VALUE_LH (Struct, Type17, NonVolatileSize); + } + if (Struct->Hdr->Length > 0x3C) { + PRINT_STRUCT_VALUE_LH (Struct, Type17, VolatileSize); + } + if (Struct->Hdr->Length > 0x44) { + PRINT_STRUCT_VALUE_LH (Struct, Type17, CacheSize); + } + if (Struct->Hdr->Length > 0x4C) { + PRINT_STRUCT_VALUE_LH (Struct, Type17, LogicalSize); + } + } + break; + + // + // 32-bit Memory Error Information (Type 18) + // + case 18: + DisplayMemoryErrorType (Struct->Type18->ErrorType, Option); + DisplayMemoryErrorGranularity ( + Struct->Type18->ErrorGranularity, + Option + ); + DisplayMemoryErrorOperation (Struct->Type18->ErrorOperation, Option); + PRINT_STRUCT_VALUE_H (Struct, Type18, VendorSyndrome); + PRINT_STRUCT_VALUE_H (Struct, Type18, MemoryArrayErrorAddress); + PRINT_STRUCT_VALUE_H (Struct, Type18, DeviceErrorAddress); + PRINT_STRUCT_VALUE_H (Struct, Type18, ErrorResolution); + break; + + // + // Memory Array Mapped Address (Type 19) + // + case 19: + PRINT_STRUCT_VALUE_H (Struct, Type19, StartingAddress); + PRINT_STRUCT_VALUE_H (Struct, Type19, EndingAddress); + PRINT_STRUCT_VALUE_H (Struct, Type19, MemoryArrayHandle); + PRINT_STRUCT_VALUE_H (Struct, Type19, PartitionWidth); + if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0xF)) { + PRINT_STRUCT_VALUE_LH (Struct, Type19, ExtendedStartingAddress); + PRINT_STRUCT_VALUE_LH (Struct, Type19, ExtendedEndingAddress); + } + break; + + // + // Memory Device Mapped Address (Type 20) + // + case 20: + PRINT_STRUCT_VALUE_H (Struct, Type20, StartingAddress); + PRINT_STRUCT_VALUE_H (Struct, Type20, EndingAddress); + PRINT_STRUCT_VALUE_H (Struct, Type20, MemoryDeviceHandle); + PRINT_STRUCT_VALUE_H (Struct, Type20, MemoryArrayMappedAddressHandle); + PRINT_STRUCT_VALUE_H (Struct, Type20, PartitionRowPosition); + PRINT_STRUCT_VALUE_H (Struct, Type20, InterleavePosition); + PRINT_STRUCT_VALUE_H (Struct, Type20, InterleavedDataDepth); + if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0x13)) { + PRINT_STRUCT_VALUE_LH (Struct, Type19, ExtendedStartingAddress); + PRINT_STRUCT_VALUE_LH (Struct, Type19, ExtendedEndingAddress); + } + break; + + // + // Built-in Pointing Device (Type 21) + // + case 21: + DisplayPointingDeviceType (Struct->Type21->Type, Option); + DisplayPointingDeviceInterface (Struct->Type21->Interface, Option); + PRINT_STRUCT_VALUE (Struct, Type21, NumberOfButtons); + break; + + // + // Portable Battery (Type 22) + // + case 22: + PRINT_PENDING_STRING (Struct, Type22, Location); + PRINT_PENDING_STRING (Struct, Type22, Manufacturer); + PRINT_PENDING_STRING (Struct, Type22, ManufactureDate); + PRINT_PENDING_STRING (Struct, Type22, SerialNumber); + PRINT_PENDING_STRING (Struct, Type22, DeviceName); + DisplayPBDeviceChemistry ( + Struct->Type22->DeviceChemistry, + Option + ); + PRINT_STRUCT_VALUE_H (Struct, Type22, DeviceCapacity); + PRINT_STRUCT_VALUE_H (Struct, Type22, DesignVoltage); + PRINT_PENDING_STRING (Struct, Type22, SBDSVersionNumber); + PRINT_STRUCT_VALUE_H (Struct, Type22, MaximumErrorInBatteryData); + PRINT_STRUCT_VALUE_H (Struct, Type22, SBDSSerialNumber); + DisplaySBDSManufactureDate ( + Struct->Type22->SBDSManufactureDate, + Option + ); + PRINT_PENDING_STRING (Struct, Type22, SBDSDeviceChemistry); + PRINT_STRUCT_VALUE_H (Struct, Type22, DesignCapacityMultiplier); + PRINT_STRUCT_VALUE_H (Struct, Type22, OEMSpecific); + break; + + // + // System Reset (Type 23) + // + case 23: + DisplaySystemResetCapabilities ( + Struct->Type23->Capabilities, + Option + ); + PRINT_STRUCT_VALUE_H (Struct, Type23, ResetCount); + PRINT_STRUCT_VALUE_H (Struct, Type23, ResetLimit); + PRINT_STRUCT_VALUE_H (Struct, Type23, TimerInterval); + PRINT_STRUCT_VALUE_H (Struct, Type23, Timeout); + break; + + // + // Hardware Security (Type 24) + // + case 24: + DisplayHardwareSecuritySettings ( + Struct->Type24->HardwareSecuritySettings, + Option + ); + break; + + // + // System Power Controls (Type 25) + // + case 25: + PRINT_STRUCT_VALUE_H (Struct, Type25, NextScheduledPowerOnMonth); + PRINT_STRUCT_VALUE_H (Struct, Type25, NextScheduledPowerOnDayOfMonth); + PRINT_STRUCT_VALUE_H (Struct, Type25, NextScheduledPowerOnHour); + PRINT_STRUCT_VALUE_H (Struct, Type25, NextScheduledPowerOnMinute); + PRINT_STRUCT_VALUE_H (Struct, Type25, NextScheduledPowerOnSecond); + break; + + // + // Voltage Probe (Type 26) + // + case 26: + PRINT_PENDING_STRING (Struct, Type26, Description); + DisplayVPLocation (*(UINT8 *) &(Struct->Type26->LocationAndStatus), Option); + DisplayVPStatus (*(UINT8 *) &(Struct->Type26->LocationAndStatus), Option); + PRINT_STRUCT_VALUE_H (Struct, Type26, MaximumValue); + PRINT_STRUCT_VALUE_H (Struct, Type26, MinimumValue); + PRINT_STRUCT_VALUE_H (Struct, Type26, Resolution); + PRINT_STRUCT_VALUE_H (Struct, Type26, Tolerance); + PRINT_STRUCT_VALUE_H (Struct, Type26, Accuracy); + PRINT_STRUCT_VALUE_H (Struct, Type26, OEMDefined); + PRINT_STRUCT_VALUE_H (Struct, Type26, NominalValue); + break; + + // + // Cooling Device (Type 27) + // + case 27: + PRINT_STRUCT_VALUE_H (Struct, Type27, TemperatureProbeHandle); + DisplayCoolingDeviceStatus (*(UINT8 *) &(Struct->Type27->DeviceTypeAndStatus), Option); + DisplayCoolingDeviceType (*(UINT8 *) &(Struct->Type27->DeviceTypeAndStatus), Option); + PRINT_STRUCT_VALUE_H (Struct, Type27, CoolingUnitGroup); + PRINT_STRUCT_VALUE_H (Struct, Type27, OEMDefined); + PRINT_STRUCT_VALUE_H (Struct, Type27, NominalSpeed); + if (AE_SMBIOS_VERSION (0x2, 0x7) && (Struct->Hdr->Length > 0xE)) { + PRINT_PENDING_STRING (Struct, Type27, Description); + } + break; + + // + // Temperature Probe (Type 28) + // + case 28: + PRINT_PENDING_STRING (Struct, Type28, Description); + DisplayTemperatureProbeStatus (*(UINT8 *) &(Struct->Type28->LocationAndStatus), Option); + DisplayTemperatureProbeLoc (*(UINT8 *) &(Struct->Type28->LocationAndStatus), Option); + PRINT_STRUCT_VALUE_H (Struct, Type28, MaximumValue); + PRINT_STRUCT_VALUE_H (Struct, Type28, MinimumValue); + PRINT_STRUCT_VALUE_H (Struct, Type28, Resolution); + PRINT_STRUCT_VALUE_H (Struct, Type28, Tolerance); + PRINT_STRUCT_VALUE_H (Struct, Type28, Accuracy); + PRINT_STRUCT_VALUE_H (Struct, Type28, OEMDefined); + PRINT_STRUCT_VALUE_H (Struct, Type28, NominalValue); + break; + + // + // Electrical Current Probe (Type 29) + // + case 29: + PRINT_PENDING_STRING (Struct, Type29, Description); + DisplayECPStatus (*(UINT8 *) &(Struct->Type29->LocationAndStatus), Option); + DisplayECPLoc (*(UINT8 *) &(Struct->Type29->LocationAndStatus), Option); + PRINT_STRUCT_VALUE_H (Struct, Type29, MaximumValue); + PRINT_STRUCT_VALUE_H (Struct, Type29, MinimumValue); + PRINT_STRUCT_VALUE_H (Struct, Type29, Resolution); + PRINT_STRUCT_VALUE_H (Struct, Type29, Tolerance); + PRINT_STRUCT_VALUE_H (Struct, Type29, Accuracy); + PRINT_STRUCT_VALUE_H (Struct, Type29, OEMDefined); + PRINT_STRUCT_VALUE_H (Struct, Type29, NominalValue); + break; + + // + // Out-of-Band Remote Access (Type 30) + // + case 30: + PRINT_PENDING_STRING (Struct, Type30, ManufacturerName); + DisplayOBRAConnections (Struct->Type30->Connections, Option); + break; + + // + // Boot Integrity Services (BIS) Entry Point (Type 31) + // + case 31: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_STRUCT_TYPE31), gShellDebug1HiiHandle); + break; + + // + // System Boot Information (Type 32) + // + case 32: + PRINT_BIT_FIELD (Struct, Type32, Reserved, 6); + DisplaySystemBootStatus (Struct->Type32->BootStatus, Option); + break; + + // + // 64-Bit Memory Error Information (Type 33) + // + case 33: + DisplayMemoryErrorType (Struct->Type33->ErrorType, Option); + DisplayMemoryErrorGranularity ( + Struct->Type33->ErrorGranularity, + Option + ); + DisplayMemoryErrorOperation (Struct->Type33->ErrorOperation, Option); + PRINT_STRUCT_VALUE_H (Struct, Type33, VendorSyndrome); + PRINT_STRUCT_VALUE_LH (Struct, Type33, MemoryArrayErrorAddress); + PRINT_STRUCT_VALUE_LH (Struct, Type33, DeviceErrorAddress); + PRINT_STRUCT_VALUE_H (Struct, Type33, ErrorResolution); + break; + + // + // Management Device (Type 34) + // + case 34: + PRINT_PENDING_STRING (Struct, Type34, Description); + DisplayMDType (Struct->Type34->Type, Option); + PRINT_STRUCT_VALUE_H (Struct, Type34, Address); + DisplayMDAddressType (Struct->Type34->AddressType, Option); + break; + + // + // Management Device Component (Type 35) + // + case 35: + PRINT_PENDING_STRING (Struct, Type35, Description); + PRINT_STRUCT_VALUE_H (Struct, Type35, ManagementDeviceHandle); + PRINT_STRUCT_VALUE_H (Struct, Type35, ComponentHandle); + PRINT_STRUCT_VALUE_H (Struct, Type35, ThresholdHandle); + break; + + // + // Management Device Threshold Data (Type 36) + // + case 36: + PRINT_STRUCT_VALUE_H (Struct, Type36, LowerThresholdNonCritical); + PRINT_STRUCT_VALUE_H (Struct, Type36, UpperThresholdNonCritical); + PRINT_STRUCT_VALUE_H (Struct, Type36, LowerThresholdCritical); + PRINT_STRUCT_VALUE_H (Struct, Type36, UpperThresholdCritical); + PRINT_STRUCT_VALUE_H (Struct, Type36, LowerThresholdNonRecoverable); + PRINT_STRUCT_VALUE_H (Struct, Type36, UpperThresholdNonRecoverable); + break; + + // + // Memory Channel (Type 37) + // + case 37: + { + UINT8 Count; + MEMORY_DEVICE *Ptr; + DisplayMemoryChannelType (Struct->Type37->ChannelType, Option); + PRINT_STRUCT_VALUE_H (Struct, Type37, MaximumChannelLoad); + PRINT_STRUCT_VALUE_H (Struct, Type37, MemoryDeviceCount); + + Count = Struct->Type37->MemoryDeviceCount; + Ptr = Struct->Type37->MemoryDevice; + for (Index = 0; Index < Count; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEM_DEVICE), gShellDebug1HiiHandle, Index + 1); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DEV_LOAD), gShellDebug1HiiHandle, Ptr[Index].DeviceLoad); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DEV_HANDLE), gShellDebug1HiiHandle, Ptr[Index].DeviceHandle); + } + } + break; + + // + // IPMI Device Information (Type 38) + // + case 38: + DisplayIPMIDIBMCInterfaceType (Struct->Type38->InterfaceType, Option); + PRINT_STRUCT_VALUE_H (Struct, Type38, IPMISpecificationRevision); + PRINT_STRUCT_VALUE_H (Struct, Type38, I2CSlaveAddress); + PRINT_STRUCT_VALUE_H (Struct, Type38, NVStorageDeviceAddress); + PRINT_STRUCT_VALUE_LH (Struct, Type38, BaseAddress); + break; + + // + // System Power Supply (Type 39) + // + case 39: + PRINT_STRUCT_VALUE_H (Struct, Type39, PowerUnitGroup); + PRINT_PENDING_STRING (Struct, Type39, Location); + PRINT_PENDING_STRING (Struct, Type39, DeviceName); + PRINT_PENDING_STRING (Struct, Type39, Manufacturer); + PRINT_PENDING_STRING (Struct, Type39, SerialNumber); + PRINT_PENDING_STRING (Struct, Type39, AssetTagNumber); + PRINT_PENDING_STRING (Struct, Type39, ModelPartNumber); + PRINT_PENDING_STRING (Struct, Type39, RevisionLevel); + PRINT_STRUCT_VALUE_H (Struct, Type39, MaxPowerCapacity); + DisplaySPSCharacteristics ( + *(UINT16 *) &(Struct->Type39->PowerSupplyCharacteristics), + Option + ); + PRINT_STRUCT_VALUE_H (Struct, Type39, InputVoltageProbeHandle); + PRINT_STRUCT_VALUE_H (Struct, Type39, CoolingDeviceHandle); + PRINT_STRUCT_VALUE_H (Struct, Type39, InputCurrentProbeHandle); + break; + + // + // Additional Information (Type 40) + // + case 40: + { + UINT8 NumberOfEntries; + UINT8 EntryLength; + ADDITIONAL_INFORMATION_ENTRY *Entries; + + EntryLength = 0; + Entries = Struct->Type40->AdditionalInfoEntries; + NumberOfEntries = Struct->Type40->NumberOfAdditionalInformationEntries; + + PRINT_STRUCT_VALUE_H (Struct, Type40, NumberOfAdditionalInformationEntries); + + for (Index = 0; Index < NumberOfEntries; Index++) { + EntryLength = Entries->EntryLength; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ENTRYLEN), gShellDebug1HiiHandle, EntryLength); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_REFERENCEDHANDLE), gShellDebug1HiiHandle, Entries->ReferencedHandle); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_REFERENCEDOFFSET), gShellDebug1HiiHandle, Entries->ReferencedOffset); + PRINT_SMBIOS_STRING (Struct, Entries->EntryString, String); + PRINT_SMBIOS_BIT_FIELD (Struct, Entries->Value, Value, EntryLength - 5); + Entries = (ADDITIONAL_INFORMATION_ENTRY *) ((UINT8 *)Entries + EntryLength); + } + } + break; + + // + // Onboard Devices Extended Information (Type 41) + // + case 41: + PRINT_PENDING_STRING (Struct, Type41, ReferenceDesignation); + ShellPrintEx(-1,-1,(((Struct->Type41->DeviceType) & 0x80) != 0) ? L"Device Enabled\n": L"Device Disabled\n"); + DisplayOnboardDeviceTypes ((Struct->Type41->DeviceType) & 0x7F, Option); + PRINT_STRUCT_VALUE_H (Struct, Type41, DeviceTypeInstance); + PRINT_STRUCT_VALUE_H (Struct, Type41, SegmentGroupNum); + PRINT_STRUCT_VALUE_H (Struct, Type41, BusNum); + PRINT_STRUCT_VALUE_H (Struct, Type41, DevFuncNum); + break; + + // + // Management Controller Host Interface (Type 42) + // + case 42: + DisplayMCHostInterfaceType (Struct->Type42->InterfaceType, Option); + if (AE_SMBIOS_VERSION (0x3, 0x2)) { + PRINT_STRUCT_VALUE_H (Struct, Type42, InterfaceTypeSpecificDataLength); + PRINT_BIT_FIELD (Struct, Type42, InterfaceTypeSpecificData, Struct->Type42->InterfaceTypeSpecificDataLength); + } + break; + + // + // TPM Device (Type 43) + // + case 43: + PRINT_BIT_FIELD (Struct, Type43, VendorID, 4); + PRINT_STRUCT_VALUE_H (Struct, Type43, MajorSpecVersion); + PRINT_STRUCT_VALUE_H (Struct, Type43, MinorSpecVersion); + PRINT_STRUCT_VALUE_H (Struct, Type43, FirmwareVersion1); + PRINT_STRUCT_VALUE_H (Struct, Type43, FirmwareVersion2); + PRINT_PENDING_STRING (Struct, Type43, Description); + DisplayTpmDeviceCharacteristics (ReadUnaligned64 ((UINT64 *) (UINTN) &(Struct->Type43->Characteristics)), Option); + PRINT_STRUCT_VALUE_H (Struct, Type43, OemDefined); + break; + + // + // Processor Additional Information (Type 44) + // + case 44: + DisplayProcessorArchitectureType (Struct->Type44->ProcessorSpecificBlock.ProcessorArchType, Option); + break; + + // + // Inactive (Type 126) + // + case 126: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INACTIVE_STRUCT), gShellDebug1HiiHandle); + break; + + // + // End-of-Table (Type 127) + // + case 127: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_THIS_STRUCT_END_TABLE), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_STRUCT_TYPE_UNDEFINED), gShellDebug1HiiHandle); + break; + } + + return EFI_SUCCESS; +} + +/** + Display BIOS Information (Type 0) information. + + @param[in] Chara The information bits. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristics ( + IN UINT64 Chara, + IN UINT8 Option + ) +{ + // + // Print header + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR), gShellDebug1HiiHandle); + // + // print option + // + PRINT_INFO_OPTION (Chara, Option); + + // + // Check all the bits and print information + // This function does not use Table because table of bits + // are designed not to deal with UINT64 + // + if (BIT (Chara, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN_BIT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ISA_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 6) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EISA_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PCI_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 8) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 9) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PLUG_PLAY_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 10) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_APM_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 11) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 12) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_SHADOWING), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 13) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VESA_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 14) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ECSD_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 15) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_CD_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 16) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SELECTED_BOOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 17) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 18) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 19) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 20) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 21) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 22) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 23) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 24) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_720_KB), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 25) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 26) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 27) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 28) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 29) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 30) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 31) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NEC_PC_98), gShellDebug1HiiHandle); + } + // + // Just print the Reserved + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_32_47), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_48_64), gShellDebug1HiiHandle); +} + +/** + Display Bios Characteristice extensions1 information. + + @param[in] Byte1 The information. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristicsExt1 ( + IN UINT8 Byte1, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (Byte1, Option); + + // + // check bit and print + // + if (BIT (Byte1, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_USB_LEGACY_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AGP_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_I2O_BOOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 6) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_1394_BOOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Byte1, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED), gShellDebug1HiiHandle); + } +} + +/** + Display Bios Characteristice extensions2 information. + + @param[in] byte2 The information. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristicsExt2 ( + IN UINT8 byte2, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION_2), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (byte2, Option); + + if (BIT (byte2, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP), gShellDebug1HiiHandle); + } + + if (BIT (byte2, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT), gShellDebug1HiiHandle); + } + + if (AE_SMBIOS_VERSION (0x2, 0x4)) { + if (BIT (byte2, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST), gShellDebug1HiiHandle); + } + if (AE_SMBIOS_VERSION (0x2, 0x7)) { + if (BIT (byte2, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UEFI_SPEC_SUPPORT), gShellDebug1HiiHandle); + } + if (BIT (byte2, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE), gShellDebug1HiiHandle); + } + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE), gShellDebug1HiiHandle, 5); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE), gShellDebug1HiiHandle, 3); + } + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE), gShellDebug1HiiHandle, 2); + } +} + +/** + Display Processor Information (Type 4) information. + + @param[in] Family The family value. + @param[in] Option The option value. +**/ +VOID +DisplayProcessorFamily ( + UINT8 Family, + UINT8 Option + ) +{ + // + // Print prompt message + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PROCESSOR_FAMILY), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (Family, Option); + + // + // Use switch to check + // + switch (Family) { + case 0x01: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTHER), gShellDebug1HiiHandle); + break; + + case 0x02: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + + case 0x03: + Print (L"8086\n"); + break; + + case 0x04: + Print (L"80286\n"); + break; + + case 0x05: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL386_PROCESSOR), gShellDebug1HiiHandle); + break; + + case 0x06: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL486_PROCESSOR), gShellDebug1HiiHandle); + break; + + case 0x07: + Print (L"8087\n"); + break; + + case 0x08: + Print (L"80287\n"); + break; + + case 0x09: + Print (L"80387\n"); + break; + + case 0x0A: + Print (L"80487\n"); + break; + + case 0x0B: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PROC_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x0C: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PRO_PROC), gShellDebug1HiiHandle); + break; + + case 0x0D: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_II_PROC), gShellDebug1HiiHandle); + break; + + case 0x0E: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PROC_MMX), gShellDebug1HiiHandle); + break; + + case 0x0F: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CELERON_PROC), gShellDebug1HiiHandle); + break; + + case 0x10: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_XEON_PROC), gShellDebug1HiiHandle); + break; + + case 0x11: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_III_PROC), gShellDebug1HiiHandle); + break; + + case 0x12: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_M1_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x13: + Print (L"M2 Family\n"); + break; + + case 0x14: + Print (L"Intel Celeron M\n"); + break; + + case 0x15: + Print (L"Intel Pentium 4 HT\n"); + break; + + case 0x18: + Print (L"AMD Duron\n"); + break; + + case 0x19: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_K5_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x1A: + Print (L"K6 Family\n"); + break; + + case 0x1B: + Print (L"K6-2\n"); + break; + + case 0x1C: + Print (L"K6-3\n"); + break; + + case 0x1D: + Print (L"AMD Althon Processor Family\n"); + break; + + case 0x1E: + Print (L"AMD 29000 Family\n"); + break; + + case 0x1F: + Print (L"K6-2+\n"); + break; + + case 0x20: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_PC_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x21: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_PC_601), gShellDebug1HiiHandle); + break; + + case 0x22: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_PC_603), gShellDebug1HiiHandle); + break; + + case 0x23: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_PC_603_PLUS), gShellDebug1HiiHandle); + break; + + case 0x24: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_PC_604), gShellDebug1HiiHandle); + break; + + case 0x25: + Print (L"Power PC 620\n"); + break; + + case 0x26: + Print (L"Power PC 704\n"); + break; + + case 0x27: + Print (L"Power PC 750\n"); + break; + + case 0x28: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_DUO), gShellDebug1HiiHandle); + break; + + case 0x29: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_DUO_MOBILE), gShellDebug1HiiHandle); + break; + + case 0x2A: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_SOLO_MOBILE), gShellDebug1HiiHandle); + break; + + case 0x2B: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_ATOM), gShellDebug1HiiHandle); + break; + + case 0x2C: + Print (L"Intel(R) Core(TM) M processor\n"); + break; + + case 0x2D: + Print (L"Intel(R) Core(TM) m3 processor\n"); + break; + + case 0x2E: + Print (L"Intel(R) Core(TM) m5 processor\n"); + break; + + case 0x2F: + Print (L"Intel(R) Core(TM) m7 processor\n"); + break; + + case 0x30: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ALPHA_FAMILY_2), gShellDebug1HiiHandle); + break; + + case 0x31: + Print (L"Alpha 21064\n"); + break; + + case 0x32: + Print (L"Alpha 21066\n"); + break; + + case 0x33: + Print (L"Alpha 21164\n"); + break; + + case 0x34: + Print (L"Alpha 21164PC\n"); + break; + + case 0x35: + Print (L"Alpha 21164a\n"); + break; + + case 0x36: + Print (L"Alpha 21264\n"); + break; + + case 0x37: + Print (L"Alpha 21364\n"); + break; + + case 0x38: + Print (L"AMD Turion II Ultra Dual-Core Mobile M Processor Family\n"); + break; + + case 0x39: + Print (L"AMD Turion II Dual-Core Mobile M Processor Family\n"); + break; + + case 0x3A: + Print (L"AMD Althon II Dual-Core M Processor Family\n"); + break; + + case 0x3B: + Print (L"AMD Opteron 6100 Series Processor\n"); + break; + + case 0x3C: + Print (L"AMD Opteron 4100 Series Processor\n"); + break; + + case 0x3D: + Print (L"AMD Opteron 6200 Series Processor\n"); + break; + + case 0x3E: + Print (L"AMD Opteron 4200 Series Processor\n"); + break; + + case 0x3F: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_FX_SERIES), gShellDebug1HiiHandle); + break; + + case 0x40: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MIPS_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x41: + Print (L"MIPS R4000\n"); + break; + + case 0x42: + Print (L"MIPS R4200\n"); + break; + + case 0x43: + Print (L"MIPS R4400\n"); + break; + + case 0x44: + Print (L"MIPS R4600\n"); + break; + + case 0x45: + Print (L"MIPS R10000\n"); + break; + + case 0x46: + Print (L"AMD C-Series Processor\n"); + break; + + case 0x47: + Print (L"AMD E-Series Processor\n"); + break; + + case 0x48: + Print (L"AMD A-Series Processor\n"); + break; + + case 0x49: + Print (L"AMD G-Series Processor\n"); + break; + + case 0x4A: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_Z_SERIES), gShellDebug1HiiHandle); + break; + + case 0x4B: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_R_SERIES), gShellDebug1HiiHandle); + break; + + case 0x4C: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_4300_SERIES), gShellDebug1HiiHandle); + break; + + case 0x4D: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_6300_SERIES), gShellDebug1HiiHandle); + break; + + case 0x4E: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_3300_SERIES), gShellDebug1HiiHandle); + break; + + case 0x4F: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_FIREPRO_SERIES), gShellDebug1HiiHandle); + break; + + case 0x50: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SPARC_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x51: + Print (L"SuperSparc\n"); + break; + + case 0x52: + Print (L"microSparc II\n"); + break; + + case 0x53: + Print (L"microSparc IIep\n"); + break; + + case 0x54: + Print (L"UltraSparc\n"); + break; + + case 0x55: + Print (L"UltraSparc II\n"); + break; + + case 0x56: + Print (L"UltraSparcIIi\n"); + break; + + case 0x57: + Print (L"UltraSparcIII\n"); + break; + + case 0x58: + Print (L"UltraSparcIIIi\n"); + break; + + case 0x60: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_68040_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x61: + Print (L"68xx\n"); + break; + + case 0x62: + Print (L"68000\n"); + break; + + case 0x63: + Print (L"68010\n"); + break; + + case 0x64: + Print (L"68020\n"); + break; + + case 0x65: + Print (L"68030\n"); + break; + + case 0x66: + Print (L"AMD Athlon(TM) X4 Quad-Core Processor Family\n"); + break; + + case 0x67: + Print (L"AMD Opteron(TM) X1000 Series Processor\n"); + break; + + case 0x68: + Print (L"AMD Opteron(TM) X2000 Series APU\n"); + break; + + case 0x69: + Print (L"AMD Opteron(TM) A-Series Processor\n"); + break; + + case 0x6A: + Print (L"AMD Opteron(TM) X3000 Series APU\n"); + break; + + case 0x6B: + Print (L"AMD Zen Processor Family\n"); + break; + + case 0x70: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_HOBBIT_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x78: + Print (L"Crusoe TM5000\n"); + break; + + case 0x79: + Print (L"Crusoe TM3000\n"); + break; + + case 0x7A: + Print (L"Efficeon TM8000\n"); + break; + + case 0x80: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_WEITEK), gShellDebug1HiiHandle); + break; + + case 0x82: + Print (L"Itanium\n"); + break; + + case 0x83: + Print (L"AMD Athlon64\n"); + break; + + case 0x84: + Print (L"AMD Opteron\n"); + break; + + case 0x85: + Print (L"AMD Sempron\n"); + break; + + case 0x86: + Print (L"AMD Turion64 Mobile\n"); + break; + + case 0x87: + Print (L"Dual-Core AMD Opteron\n"); + break; + + case 0x88: + Print (L"AMD Athlon 64X2 DualCore\n"); + break; + + case 0x89: + Print (L"AMD Turion 64X2 Mobile\n"); + break; + + case 0x8A: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0x8B: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_THIRD_GENERATION), gShellDebug1HiiHandle); + break; + + case 0x8C: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_FX_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0x8D: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_X4_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0x8E: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_X2_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0x8F: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_ATHLON_X2_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0x90: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PA_RISC_FAMILY), gShellDebug1HiiHandle); + break; + + case 0x91: + Print (L"PA-RISC 8500\n"); + break; + + case 0x92: + Print (L"PA-RISC 8000\n"); + break; + + case 0x93: + Print (L"PA-RISC 7300LC\n"); + break; + + case 0x94: + Print (L"PA-RISC 7200\n"); + break; + + case 0x95: + Print (L"PA-RISC 7100LC\n"); + break; + + case 0x96: + Print (L"PA-RISC 7100\n"); + break; + + case 0xA0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_V30_FAMILY), gShellDebug1HiiHandle); + break; + + case 0xA1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3200_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xA2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3000_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5300_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xA4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5100_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5000_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_LV_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_ULV_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA8: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7100_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xA9: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5400_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xAA: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xAB: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5200_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xAC: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7200_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xAD: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7300_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xAE: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7400_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xAF: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7400_SERIES_MULTI_CORE), gShellDebug1HiiHandle); + break; + + case 0xB0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PENTIUM_III_XEON), gShellDebug1HiiHandle); + break; + + case 0xB1: + Print (L"Pentium III Processorwith Intel SpeedStep Technology\n"); + break; + + case 0xB2: + Print (L"Pentium 4 processor\n"); + break; + + case 0xB3: + Print (L"Intel Xeon Processor\n"); + break; + + case 0xB4: + Print (L"AS400 Family\n"); + break; + + case 0xB5: + Print (L"Intel Xeon processor MP\n"); + break; + + case 0xB6: + Print (L"AMD Althon XP Processor Family\n"); + break; + + case 0xB7: + Print (L"AMD Althon MP Promcessor Family\n"); + break; + + case 0xB8: + Print (L"Intel Itanium 2 processor\n"); + break; + + case 0xB9: + Print (L"Intel Penium M processor\n"); + break; + + case 0xBA: + Print (L"Intel Celeron D processor\n"); + break; + + case 0xBB: + Print (L"Intel Pentium D processor\n"); + break; + + case 0xBC: + Print (L"Intel Pentium Processor Extreme Edition\n"); + break; + + case 0xBD: + Print (L"Intel Core Solo Processor\n"); + break; + + case 0xBF: + Print (L"Intel Core 2 Duo Processor\n"); + break; + + case 0xC0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_SOLO), gShellDebug1HiiHandle); + break; + + case 0xC1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_EXTREME), gShellDebug1HiiHandle); + break; + + case 0xC2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_QUAD), gShellDebug1HiiHandle); + break; + + case 0xC3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_EXTREME), gShellDebug1HiiHandle); + break; + + case 0xC4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_DUO_MOBILE), gShellDebug1HiiHandle); + break; + + case 0xC5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_SOLO_MOBILE), gShellDebug1HiiHandle); + break; + + case 0xC6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_I7), gShellDebug1HiiHandle); + break; + + case 0xC7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_CELERON_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xC8: + Print (L"IBM 390\n"); + break; + + case 0xC9: + Print (L"G4\n"); + break; + + case 0xCA: + Print (L"G5\n"); + break; + + case 0xCB: + Print (L"G6\n"); + break; + + case 0xCC: + Print (L"zArchitecture\n"); + break; + + case 0xCD: + Print (L"Intel Core i5 processor\n"); + break; + + case 0xCE: + Print (L"Intel Core i3 processor\n"); + break; + + case 0xCF: + Print (L"Intel Core i9 processor\n"); + break; + + case 0xD2: + Print (L"ViaC7M\n"); + break; + + case 0xD3: + Print (L"ViaC7D\n"); + break; + + case 0xD4: + Print (L"ViaC7\n"); + break; + + case 0xD5: + Print (L"Eden\n"); + break; + + case 0xD6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_MULTI_CORE), gShellDebug1HiiHandle); + break; + + case 0xD7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xD8: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xDA: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xDB: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xDD: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xDE: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xDF: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_MULTI_CORE), gShellDebug1HiiHandle); + break; + + case 0xE0: + Print (L"Multi-Core Intel Xeon processor 3400 Series\n"); + break; + + case 0xE4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_3000_SERIES), gShellDebug1HiiHandle); + break; + + case 0xE5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_SEMPRON_II), gShellDebug1HiiHandle); + break; + + + case 0xE6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_EMBEDDED_OPTERON_QUAD_CORE), gShellDebug1HiiHandle); + break; + + case 0xE7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_TRIPLE_CORE), gShellDebug1HiiHandle); + break; + + case 0xE8: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_TURION_ULTRA_DUAL_CORE_MOBILE), gShellDebug1HiiHandle); + break; + + case 0xE9: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_TURION_DUAL_CORE_MOBILE), gShellDebug1HiiHandle); + break; + + case 0xEA: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_ATHLON_DUAL_CORE), gShellDebug1HiiHandle); + break; + + case 0xEB: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AMD_SEMPRON_SI), gShellDebug1HiiHandle); + break; + + case 0xEC: + Print (L"AMD Phenom II Processor Family\n"); + break; + + case 0xED: + Print (L"AMD Althon II Processor Family\n"); + break; + + case 0xEE: + Print (L"Six-Core AMD Opteron Processor Family\n"); + break; + + case 0xEF: + Print (L"AMD Sempron M Processor Family\n"); + break; + + case 0xFA: + Print (L"i860\n"); + break; + + case 0xFB: + Print (L"i960\n"); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_PROC_FAMILY), gShellDebug1HiiHandle); + } + // + // end switch + // +} + +/** + Display processor family information. + + @param[in] Family2 The family value. + @param[in] Option The option value. +**/ +VOID +DisplayProcessorFamily2 ( + IN UINT16 Family2, + IN UINT8 Option + ) +{ + // + // Print prompt message + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PROCESSOR_FAMILY), gShellDebug1HiiHandle); + + // + // Print option + // + PRINT_INFO_OPTION (Family2, Option); + + // + // Use switch to check + // + switch (Family2) { + case 0x100: + Print (L"ARMv7\n"); + break; + + case 0x101: + Print (L"ARMv8\n"); + break; + + case 0x104: + Print (L"SH-3\n"); + break; + + case 0x105: + Print (L"SH-4\n"); + break; + + case 0x118: + Print (L"ARM\n"); + break; + + case 0x119: + Print (L"StrongARM\n"); + break; + + case 0x12C: + Print (L"6x86\n"); + break; + + case 0x12D: + Print (L"MediaGX\n"); + break; + + case 0x12E: + Print (L"MII\n"); + break; + + case 0x140: + Print (L"WinChip\n"); + break; + + case 0x15E: + Print (L"DSP\n"); + break; + + case 0x1F4: + Print (L"Video Processor\n"); + break; + + case 0x200: + Print (L"RISC-V RV32\n"); + break; + + case 0x201: + Print (L"RISC-V RV64\n"); + break; + + case 0x202: + Print (L"RISC-V RV128\n"); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_PROC_FAMILY), gShellDebug1HiiHandle); + } + +} + +/** + Display processor voltage information. + + @param[in] Voltage The Voltage. + Bit 7 Set to 0, indicating 'legacy' mode for processor voltage + Bits 6:4 Reserved, must be zero + Bits 3:0 Voltage Capability. + A Set bit indicates that the voltage is supported. + Bit 0 - 5V + Bit 1 - 3.3V + Bit 2 - 2.9V + Bit 3 - Reserved, must be zero. + + Note: + Setting of multiple bits indicates the socket is configurable + If bit 7 is set to 1, the remaining seven bits of the field are set to + contain the processor's current voltage times 10. + For example, the field value for a processor voltage of 1.8 volts would be + 92h = 80h + (1.8 * 10) = 80h + 18 = 80h +12h. + + @param[in] Option The option. +**/ +VOID +DisplayProcessorVoltage ( + IN UINT8 Voltage, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PROC_INFO), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (Voltage, Option); + + if (BIT (Voltage, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PROC_CURRENT_VOLTAGE), gShellDebug1HiiHandle, (Voltage - 0x80)); + } else { + if (BIT (Voltage, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_5V_SUPOPRTED), gShellDebug1HiiHandle); + } + + if (BIT (Voltage, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_33V_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Voltage, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_29V_SUPPORTED), gShellDebug1HiiHandle); + } + // + // check the reserved zero bits: + // + if (BIT (Voltage, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT3_NOT_ZERO), gShellDebug1HiiHandle); + } + + if (BIT (Voltage, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT4_NOT_ZERO), gShellDebug1HiiHandle); + } + + if (BIT (Voltage, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT5_NOT_ZERO), gShellDebug1HiiHandle); + } + + if (BIT (Voltage, 6) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT6_NOT_ZERO), gShellDebug1HiiHandle); + } + } +} + +/** + Display processor information. + + @param[in] Status The status. +Bit 7 Reserved, must be 0 +Bit 6 CPU Socket Populated + 1 - CPU Socket Populated + 0 - CPU Socket Unpopulated +Bits 5:3 Reserved, must be zero +Bits 2:0 CPU Status + 0h - Unknown + 1h - CPU Enabled + 2h - CPU Disabled by User via BIOS Setup + 3h - CPU Disabled By BIOS (POST Error) + 4h - CPU is Idle, waiting to be enabled. + 5-6h - Reserved + 7h - Other + + @param[in] Option The option +**/ +VOID +DisplayProcessorStatus ( + IN UINT8 Status, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PROC_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + + if (BIT (Status, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT7_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (Status, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT5_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (Status, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT4_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (Status, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT3_NOT_ZERO), gShellDebug1HiiHandle); + } + // + // Check BIT 6 + // + if (BIT (Status, 6) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_SOCKET_POPULATED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_SOCKET_UNPOPULATED), gShellDebug1HiiHandle); + } + // + // Check BITs 2:0 + // + switch (Status & 0x07) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_ENABLED), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_DISABLED_BY_USER), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_DIABLED_BY_BIOS), gShellDebug1HiiHandle); + break; + + case 4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CPU_IDLE), gShellDebug1HiiHandle); + break; + + case 7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTHERS), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED), gShellDebug1HiiHandle); + } +} + +/** + Display information about Memory Controller Information (Type 5). + + @param[in] Size Memory size. + @param[in] SlotNum Which slot is this about. + @param[in] Option Option for the level of detail output required. +**/ +VOID +DisplayMaxMemoryModuleSize ( + IN UINT8 Size, + IN UINT8 SlotNum, + IN UINT8 Option + ) +{ + UINTN MaxSize; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SIZE_LARGEST_MEM), gShellDebug1HiiHandle); + // + // MaxSize is determined by follow formula + // + MaxSize = (UINTN) 1 << Size; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_MB), gShellDebug1HiiHandle, MaxSize); + + if (Option >= SHOW_DETAIL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MAX_AMOUNT_MEM), gShellDebug1HiiHandle); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_MB), gShellDebug1HiiHandle, MaxSize, SlotNum, MaxSize * SlotNum); + } +} + +/** + Display information about memory configuration handles. + + @param[in] Handles The buffer of handles to output info on. + @param[in] SlotNum The number of handles in the above buffer. + @param[in] Option Option for the level of detail output required. +**/ +VOID +DisplayMemoryModuleConfigHandles ( + IN UINT16 *Handles, + IN UINT8 SlotNum, + IN UINT8 Option + ) +{ + UINT8 Index; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_HANDLES_CONTROLLED), gShellDebug1HiiHandle, SlotNum); + + if (Option >= SHOW_DETAIL) { + // + // No handle, Handles is INVALID. + // + if (SlotNum == 0) { + return ; + } + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_HANDLES_LIST_CONTROLLED), gShellDebug1HiiHandle); + for (Index = 0; Index < SlotNum; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_HANDLE), gShellDebug1HiiHandle, Index + 1, Handles[Index]); + } + } +} + +/** + Display Memory Module Information (Type 6). + + @param[in] BankConnections + @param[in] Option +**/ +VOID +DisplayMmBankConnections ( + IN UINT8 BankConnections, + IN UINT8 Option + ) +{ + UINT8 High; + UINT8 Low; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BANK_CONNECTIONS), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (BankConnections, Option); + + // + // Divide it to high and low + // + High = (UINT8) (BankConnections & 0xF0); + Low = (UINT8) (BankConnections & 0x0F); + if (High != 0xF) { + if (Low != 0xF) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BANK_RAS), gShellDebug1HiiHandle, High, Low, High, Low); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BANK_RAS_2), gShellDebug1HiiHandle, High, High); + } + } else { + if (Low != 0xF) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BANK_RAS_2), gShellDebug1HiiHandle, Low, Low); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NO_BANKS_CONNECTED), gShellDebug1HiiHandle); + } + } +} + +/** + Display memory informcation. + + Bits 0:6 Size (n), + where 2**n is the size in MB with three special-case values: + 7Dh Not determinable (Installed Size only) + 7Eh Module is installed, but no memory has been enabled + 7Fh Not installed + Bit 7 Defines whether the memory module has a single- (0) + or double-bank (1) connection. + + @param[in] Size - The size + @param[in] Option - The option +**/ +VOID +DisplayMmMemorySize ( + IN UINT8 Size, + IN UINT8 Option + ) +{ + UINT8 Value; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEMORY_SIZE), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (Size, Option); + + // + // Get the low bits(0-6 bit) + // + Value = (UINT8) (Size & 0x7F); + if (Value == 0x7D) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEM_SIZE_NOT_DETERMINABLE), gShellDebug1HiiHandle); + } else if (Value == 0x7E) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MODULE_INSTALLED), gShellDebug1HiiHandle); + } else if (Value == 0x7F) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_INSTALLED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEM_SIZE), gShellDebug1HiiHandle, 1 << Value); + } + + if (BIT (Size, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEM_MODULE_DOUBLE_BANK), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MEM_MODULE_SINGLE_BANK), gShellDebug1HiiHandle); + } +} + +/** + Display Cache Configuration. + + @param[in] CacheConfiguration Cache Configuration. +Bits 15:10 Reserved, must be 0 +Bits 9:8 Operational Mode + 0h - Write Through + 1h - Write Back + 2h - Varies with Memory Address + 3h - Unknown +Bit 7 Enabled/Disabled + 1 - Enabled + 0 - Disabled +Bits 6:5 Location + 0h - Internal + 1h - External + 2h - Reserved + 3h - Unknown +Bit 4 Reserved, must be zero +Bit 3 Cache Socketed + 1 - Socketed + 0 - Unsocketed +Bits 2:0 Cache Level + 1 through 8 (For example, an L1 cache would + use value 000b and an L3 cache would use 010b.) + + @param[in] Option The option +**/ +VOID +DisplayCacheConfiguration ( + IN UINT16 CacheConfiguration, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_CONFIGURATION), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (CacheConfiguration, Option); + + if (BIT (CacheConfiguration, 15) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT15_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 14) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT14_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 13) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT13_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 12) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT12_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 11) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT11_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 10) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT10_NOT_ZERO), gShellDebug1HiiHandle); + } else if (BIT (CacheConfiguration, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BIT4_NOT_ZERO), gShellDebug1HiiHandle); + } + + // + // Check BITs 9:8 + // + switch ((CacheConfiguration & 0x300) >> 8) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_WRITE_THROUGH), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_WRITE_BACK), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_VARIES_WITH_MEM_ADDR), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } + + // + // Check BIT 7 + // + if (BIT (CacheConfiguration, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DISABLED), gShellDebug1HiiHandle); + } + + // + // Check BITs 6:5 + // + switch ((CacheConfiguration & 0x60) >> 5) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_INTERNAL), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_EXTERNAL), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } + + // + // Check BIT 3 + // + if (BIT (CacheConfiguration, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_SOCKETED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_NOT_SOCKETED), gShellDebug1HiiHandle); + } + + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CACHE_LEVEL), gShellDebug1HiiHandle, (CacheConfiguration & 0x07) + 1); +} + +/** + The Slot ID field of the System Slot structure provides a mechanism to + correlate the physical attributes of the slot to its logical access method + (which varies based on the Slot Type field). + + @param[in] SlotId - The slot ID + @param[in] SlotType - The slot type + @param[in] Option - The Option +**/ +VOID +DisplaySystemSlotId ( + IN UINT16 SlotId, + IN UINT8 SlotType, + IN UINT8 Option + ) +{ + // + // Display slot type first + // + DisplaySystemSlotType (SlotType, Option); + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SLOT_ID), gShellDebug1HiiHandle); + // + // print option + // + PRINT_INFO_OPTION (SlotType, Option); + + switch (SlotType) { + // + // Slot Type: MCA + // + case 0x04: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_MICRO_CHAN), gShellDebug1HiiHandle); + if (SlotId > 0 && SlotId < 15) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle); + } + break; + + // + // EISA + // + case 0x05: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_EISA_NUM), gShellDebug1HiiHandle); + if (SlotId > 0 && SlotId < 15) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle); + } + break; + + // + // Slot Type: PCI + // + case 0x06: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId); + break; + + // + // PCMCIA + // + case 0x07: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_IDENTIFIES_ADAPTER_NUM), gShellDebug1HiiHandle, SlotId); + break; + + // + // Slot Type: PCI-E + // + case 0xA5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId); + break; + + default: + if ((SlotType >= 0x0E && SlotType <= 0x12) || (SlotType >= 0xA6 && SlotType <= 0xB6)){ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_SLOT_ID), gShellDebug1HiiHandle); + } + } +} + +/** + Display System Boot Information (Type 32) information. + + @param[in] Parameter The parameter. + @param[in] Option The options. +**/ +VOID +DisplaySystemBootStatus ( + IN UINT8 Parameter, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_BOOT_STATUS), gShellDebug1HiiHandle); + // + // Print option + // + PRINT_INFO_OPTION (Parameter, Option); + + // + // Check value and print + // + if (Parameter == 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NO_ERRORS_DETECTED), gShellDebug1HiiHandle); + } else if (Parameter == 1) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NO_BOOTABLE_MEDIA), gShellDebug1HiiHandle); + } else if (Parameter == 2) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NORMAL_OP_SYSTEM), gShellDebug1HiiHandle); + } else if (Parameter == 3) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FIRMWARE_DETECTED), gShellDebug1HiiHandle); + } else if (Parameter == 4) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OP_SYSTEM), gShellDebug1HiiHandle); + } else if (Parameter == 5) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_USER_REQUESTED_BOOT), gShellDebug1HiiHandle); + } else if (Parameter == 6) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_SECURITY_VIOLATION), gShellDebug1HiiHandle); + } else if (Parameter == 7) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PREV_REQ_IMAGE), gShellDebug1HiiHandle); + } else if (Parameter == 8) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_WATCHDOG_TIMER), gShellDebug1HiiHandle); + } else if (Parameter >= 9 && Parameter <= 127) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RSVD_FUTURE_ASSIGNMENT), gShellDebug1HiiHandle); + } else if (Parameter >= 128 && Parameter <= 191) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VENDOR_OEM_SPECIFIC), gShellDebug1HiiHandle); + } else if (Parameter >= 192) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_PRODUCT_SPEC_IMPLMENTATION), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_VALUE), gShellDebug1HiiHandle); + } +} + +/** + Display Portable Battery (Type 22) information. + + The date the cell pack was manufactured, in packed format: + Bits 15:9 Year, biased by 1980, in the range 0 to 127. + Bits 8:5 Month, in the range 1 to 12. + Bits 4:0 Date, in the range 1 to 31. + For example, 01 February 2000 would be identified as + 0010 1000 0100 0001b (0x2841). + + @param[in] Date The date + @param[in] Option The option +**/ +VOID +DisplaySBDSManufactureDate ( + IN UINT16 Date, + IN UINT8 Option + ) +{ + UINTN Day; + UINTN Month; + UINTN Year; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SBDS_MANUFACTURE_DATE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Date, Option); + // + // Print date + // + Day = Date & 0x001F; + Month = (Date & 0x01E0) >> 5; + Year = ((Date & 0xFE00) >> 9) + 1980; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MONTH_DAY_YEAR), gShellDebug1HiiHandle, Day, Month, Year); + +} + +/** + Display System Reset (Type 23) information. + + +Identifies the system-reset capabilities for the system. + Bits 7:6 Reserved for future assignment via this specification, set to 00b. + Bit 5 System contains a watchdog timer, either True (1) or False (0). + Bits 4:3 Boot Option on Limit. + Identifies the system action to be taken when the Reset Limit is reached, one of: + 00b Reserved, do not use. + 01b Operating system + 10b System utilities + 11b Do not rebootBits + 2:1 Boot Option. Indicates the action to be taken following a watchdog reset, one of: + 00b Reserved, do not use. + 01b Operating system + 10b System utilities + 11b Do not reboot + Bit 0 Status. + 1b The system reset is enabled by the user + 0b The system reset is not enabled by the user + + @param[in] Reset Reset + @param[in] Option The option +**/ +VOID +DisplaySystemResetCapabilities ( + IN UINT8 Reset, + IN UINT8 Option + ) +{ + UINTN Temp; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_RESET_CAPABILITIES), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Reset, Option); + + // + // Check reserved bits 7:6 + // + if ((Reset & 0xC0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_RESERVED_ZERO), gShellDebug1HiiHandle); + } + // + // Watch dog + // + if (BIT (Reset, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_WATCHDOG_TIMER_2), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_NOT_CONTAIN_TIMER), gShellDebug1HiiHandle); + } + // + // Boot Option on Limit + // + Temp = (Reset & 0x18) >> 3; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BOOT_OPTION_LIMIT), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OP_SYSTEM_2), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_UTIL), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DO_NOT_REBOOT), gShellDebug1HiiHandle); + break; + } + // + // Boot Option + // + Temp = (Reset & 0x06) >> 1; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BOOT_OPTION), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OP_SYSTEM_2), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SYSTEM_UTIL), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DO_NOT_REBOOT), gShellDebug1HiiHandle); + break; + } + // + // Reset enable flag + // + if ((Reset & 0x01) != 0) { + Print (L"The system reset is enabled by the user\n"); + } else { + Print (L"The system reset is disabled by the user\n"); + } +} + +/** + Display Hardware Security (Type 24) information. + + +Identifies the password and reset status for the system: + +Bits 7:6 Power-on Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown +Bits 5:4 Keyboard Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown +Bits 3:2 Administrator Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown +Bits 1:0 Front Panel Reset Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown + + @param[in] Settings The device settings. + @param[in] Option The device options. +**/ +VOID +DisplayHardwareSecuritySettings ( + IN UINT8 Settings, + IN UINT8 Option + ) +{ + UINTN Temp; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_HARDWARE_SECURITY_SET), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Settings, Option); + + // + // Power-on Password Status + // + Temp = (Settings & 0xC0) >> 6; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_ON_PASSWORD), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DISABLED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED_NEWLINE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_IMPLEMENTED), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } + // + // Keyboard Password Status + // + Temp = (Settings & 0x30) >> 4; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_PASSWORD), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DISABLED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED_NEWLINE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_IMPLEMENTED), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } + // + // Administrator Password Status + // + Temp = (Settings & 0x0C) >> 2; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ADMIN_PASSWORD_STATUS), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DISABLED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED_NEWLINE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_IMPLEMENTED), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } + // + // Front Panel Reset Status + // + Temp = Settings & 0x3; + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_FRONT_PANEL_RESET), gShellDebug1HiiHandle); + switch (Temp) { + case 0: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_DISABLED), gShellDebug1HiiHandle); + break; + + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ENABLED_NEWLINE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_IMPLEMENTED), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + } +} + +/** + Display Out-of-Band Remote Access (Type 30) information. + + @param[in] Connections The device characteristics. + @param[in] Option The device options. +**/ +VOID +DisplayOBRAConnections ( + IN UINT8 Connections, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CONNECTIONS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Connections, Option); + + // + // Check reserved bits 7:2 + // + if ((Connections & 0xFC) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_RESERVED_ZERO_2), gShellDebug1HiiHandle); + } + // + // Outbound Connection + // + if (BIT (Connections, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OUTBOUND_CONN_ENABLED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTUBOUND_CONN_DISABLED), gShellDebug1HiiHandle); + } + // + // Inbound Connection + // + if (BIT (Connections, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INBOIUND_CONN_ENABLED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INBOUND_CONN_DISABLED), gShellDebug1HiiHandle); + } +} + +/** + Display System Power Supply (Type 39) information. + + @param[in] Characteristics The device characteristics. + @param[in] Option The device options. +**/ +VOID +DisplaySPSCharacteristics ( + IN UINT16 Characteristics, + IN UINT8 Option + ) +{ + UINTN Temp; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_CHAR), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Characteristics, Option); + + // + // Check reserved bits 15:14 + // + if ((Characteristics & 0xC000) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_15_14_RSVD), gShellDebug1HiiHandle); + } + // + // Bits 13:10 - DMTF Power Supply Type + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TYPE), gShellDebug1HiiHandle); + Temp = (Characteristics & 0x1C00) >> 10; + switch (Temp) { + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTHER_SPACE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LINEAR), gShellDebug1HiiHandle); + break; + + case 4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_SWITCHING), gShellDebug1HiiHandle); + break; + + case 5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BATTERY), gShellDebug1HiiHandle); + break; + + case 6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UPS), gShellDebug1HiiHandle); + break; + + case 7: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CONVERTER), gShellDebug1HiiHandle); + break; + + case 8: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_REGULATOR), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_2), gShellDebug1HiiHandle); + } + // + // Bits 9:7 - Status + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_STATUS_DASH), gShellDebug1HiiHandle); + Temp = (Characteristics & 0x380) >> 7; + switch (Temp) { + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTHER_SPACE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OK), gShellDebug1HiiHandle); + break; + + case 4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NON_CRITICAL), gShellDebug1HiiHandle); + break; + + case 5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_CRITICAL_POWER_SUPPLY), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED), gShellDebug1HiiHandle); + } + // + // Bits 6:3 - DMTF Input Voltage Range Switching + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_INPUT_VOLTAGE_RANGE), gShellDebug1HiiHandle); + Temp = (Characteristics & 0x78) >> 3; + switch (Temp) { + case 1: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_OTHER_SPACE), gShellDebug1HiiHandle); + break; + + case 2: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNKNOWN), gShellDebug1HiiHandle); + break; + + case 3: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MANUAL), gShellDebug1HiiHandle); + break; + + case 4: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_AUTO_SWITCH), gShellDebug1HiiHandle); + break; + + case 5: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_WIDE_RANGE), gShellDebug1HiiHandle); + break; + + case 6: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_NOT_APPLICABLE), gShellDebug1HiiHandle); + break; + + default: + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_3), gShellDebug1HiiHandle); + break; + } + // + // Power supply is unplugged from the wall + // + if (BIT (Characteristics, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_UNPLUGGED), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_PLUGGED), gShellDebug1HiiHandle); + } + // + // Power supply is present + // + if (BIT (Characteristics, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_PRESENT), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_NOT_PRESENT), gShellDebug1HiiHandle); + } + // + // hot replaceable + // + if (BIT (Characteristics, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_REPLACE), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_NOT_REPLACE), gShellDebug1HiiHandle); + } +} + +/** + Display TPM Device (Type 43) Characteristics. + + @param[in] Chara The information bits. + @param[in] Option The optional information. +**/ +VOID +DisplayTpmDeviceCharacteristics ( + IN UINT64 Chara, + IN UINT8 Option + ) +{ + // + // Print header + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CHAR), gShellDebug1HiiHandle); + // + // print option + // + PRINT_INFO_OPTION (Chara, Option); + + // + // Check all the bits and print information + // This function does not use Table because table of bits + // are designed not to deal with UINT64 + // + if (BIT (Chara, 0) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 1) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT), gShellDebug1HiiHandle); + } + if (BIT (Chara, 2) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CHAR_NOT_SUPPORTED), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 3) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_FWU), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_PLAT_SW), gShellDebug1HiiHandle); + } + + if (BIT (Chara, 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_OEM), gShellDebug1HiiHandle); + } + + // + // Just print the Reserved + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_06_63), gShellDebug1HiiHandle); + +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.h new file mode 100644 index 00000000..021139d4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.h @@ -0,0 +1,441 @@ +/** @file + Module to clarify the element info of the smbios structure. + + Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2017 - 2019 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMBIOS_PRINT_INFO_H_ +#define _SMBIOS_PRINT_INFO_H_ + +#include <IndustryStandard/SmBios.h> + +extern UINT8 SmbiosMajorVersion; +extern UINT8 SmbiosMinorVersion; + +#define SHOW_NONE 0x00 +#define SHOW_OUTLINE 0x01 +#define SHOW_NORMAL 0x02 +#define SHOW_DETAIL 0x03 +// +// SHOW_ALL: WaitEnter() not wait input. +// +#define SHOW_ALL 0x04 +#define SHOW_STATISTICS 0x05 + +#define AS_UINT16(pData) (*((UINT16 *) pData)) +#define AS_UINT32(pData) (*((UINT32 *) pData)) +#define AS_UINT64(pData) (*((UINT64 *) pData)) + +/** + Print the info of EPS(Entry Point Structure). + + @param[in] SmbiosTable Pointer to the SMBIOS table entry point. + @param[in] Option Display option. +**/ +VOID +SmbiosPrintEPSInfo ( + IN SMBIOS_TABLE_ENTRY_POINT *SmbiosTable, + IN UINT8 Option + ); + +/** + Print the info of 64-bit EPS(Entry Point Structure). + + @param[in] SmbiosTable Pointer to the SMBIOS table entry point. + @param[in] Option Display option. +**/ +VOID +Smbios64BitPrintEPSInfo ( + IN SMBIOS_TABLE_3_0_ENTRY_POINT *SmbiosTable, + IN UINT8 Option + ); + +/** + This function print the content of the structure pointed by Struct. + + @param[in] Struct Point to the structure to be printed. + @param[in] Option Print option of information detail. + + @retval EFI_SUCCESS Successfully Printing this function. + @retval EFI_INVALID_PARAMETER Invalid Structure. + @retval EFI_UNSUPPORTED Unsupported. +**/ +EFI_STATUS +SmbiosPrintStructure ( + IN SMBIOS_STRUCTURE_POINTER *Struct, + IN UINT8 Option + ); + +/** + Display BIOS Information (Type 0) information. + + @param[in] Chara The information bits. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristics ( + IN UINT64 Chara, + IN UINT8 Option + ); + +/** + Display Bios Characteristice extensions1 information. + + @param[in] Byte1 The information. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristicsExt1 ( + IN UINT8 Byte1, + IN UINT8 Option + ); + +/** + Display Bios Characteristice extensions2 information. + + @param[in] Byte2 The information. + @param[in] Option The optional information. +**/ +VOID +DisplayBiosCharacteristicsExt2 ( + IN UINT8 Byte2, + IN UINT8 Option + ); + +/** + Display Processor Information (Type 4) information. + + @param[in] Family The family value. + @param[in] Option The option value. +**/ +VOID +DisplayProcessorFamily ( + UINT8 Family, + UINT8 Option + ); + +/** + Display processor family information. + + @param[in] Family2 The family value. + @param[in] Option The option value. +**/ +VOID +DisplayProcessorFamily2 ( + IN UINT16 Family2, + IN UINT8 Option + ); + +/** + Display processor voltage information. + + @param[in] Voltage The Voltage. + Bit 7 Set to 0, indicating 'legacy' mode for processor voltage + Bits 6:4 Reserved, must be zero + Bits 3:0 Voltage Capability. + A Set bit indicates that the voltage is supported. + Bit 0 - 5V + Bit 1 - 3.3V + Bit 2 - 2.9V + Bit 3 - Reserved, must be zero. + + Note: + Setting of multiple bits indicates the socket is configurable + If bit 7 is set to 1, the remaining seven bits of the field are set to + contain the processor's current voltage times 10. + For example, the field value for a processor voltage of 1.8 volts would be + 92h = 80h + (1.8 * 10) = 80h + 18 = 80h +12h. + + @param[in] Option The option. +**/ +VOID +DisplayProcessorVoltage ( + IN UINT8 Voltage, + IN UINT8 Option + ); + +/** + Display processor information. + + @param[in] Status The status. +Bit 7 Reserved, must be 0 +Bit 6 CPU Socket Populated + 1 - CPU Socket Populated + 0 - CPU Socket Unpopulated +Bits 5:3 Reserved, must be zero +Bits 2:0 CPU Status + 0h - Unknown + 1h - CPU Enabled + 2h - CPU Disabled by User via BIOS Setup + 3h - CPU Disabled By BIOS (POST Error) + 4h - CPU is Idle, waiting to be enabled. + 5-6h - Reserved + 7h - Other + + @param[in] Option The option +**/ +VOID +DisplayProcessorStatus ( + IN UINT8 Status, + IN UINT8 Option + ); + +/** + Display information about Memory Controller Information (Type 5). + + @param[in] Size Memory size. + @param[in] SlotNum Which slot is this about. + @param[in] Option Option for the level of detail output required. +**/ +VOID +DisplayMaxMemoryModuleSize ( + IN UINT8 Size, + IN UINT8 SlotNum, + IN UINT8 Option + ); + +/** + Display information about memory configuration handles. + + @param[in] Handles The buffer of handles to output info on. + @param[in] SlotNum The number of handles in the above buffer. + @param[in] Option Option for the level of detail output required. +**/ +VOID +DisplayMemoryModuleConfigHandles ( + IN UINT16 *Handles, + IN UINT8 SlotNum, + IN UINT8 Option + ); + +/** + Display Memory Module Information (Type 6). + + @param[in] BankConnections + @param[in] Option +**/ +VOID +DisplayMmBankConnections ( + IN UINT8 BankConnections, + IN UINT8 Option + ); + +/** + Display memory informcation. + + Bits 0:6 Size (n), + where 2**n is the size in MB with three special-case values: + 7Dh Not determinable (Installed Size only) + 7Eh Module is installed, but no memory has been enabled + 7Fh Not installed + Bit 7 Defines whether the memory module has a single- (0) + or double-bank (1) connection. + + @param[in] Size - The size + @param[in] Option - The option +**/ +VOID +DisplayMmMemorySize ( + IN UINT8 Size, + IN UINT8 Option + ); + +/** + Display Cache Configuration. + + @param[in] CacheConfiguration Cache Configuration. +Bits 15:10 Reserved, must be 0 +Bits 9:8 Operational Mode + 0h - Write Through + 1h - Write Back + 2h - Varies with Memory Address + 3h - Unknown +Bit 7 Enabled/Disabled + 1 - Enabled + 0 - Disabled +Bits 6:5 Location + 0h - Internal + 1h - External + 2h - Reserved + 3h - Unknown +Bit 4 Reserved, must be zero +Bit 3 Cache Socketed + 1 - Socketed + 0 - Unsocketed +Bits 2:0 Cache Level + 1 through 8 (For example, an L1 cache would + use value 000b and an L3 cache would use 010b.) + + @param[in] Option The option +**/ +VOID +DisplayCacheConfiguration ( + IN UINT16 CacheConfiguration, + IN UINT8 Option + ); + +/** + The Slot ID field of the System Slot structure provides a mechanism to + correlate the physical attributes of the slot to its logical access method + (which varies based on the Slot Type field). + + @param[in] SlotId - The slot ID + @param[in] SlotType - The slot type + @param[in] Option - The Option +**/ +VOID +DisplaySystemSlotId ( + IN UINT16 SlotId, + IN UINT8 SlotType, + IN UINT8 Option + ); + +/** + Display Portable Battery (Type 22) information. + + The date the cell pack was manufactured, in packed format: + Bits 15:9 Year, biased by 1980, in the range 0 to 127. + Bits 8:5 Month, in the range 1 to 12. + Bits 4:0 Date, in the range 1 to 31. + For example, 01 February 2000 would be identified as + 0010 1000 0100 0001b (0x2841). + + @param[in] Date The date + @param[in] Option The option +**/ +VOID +DisplaySBDSManufactureDate ( + IN UINT16 Date, + IN UINT8 Option + ); + +/** + Display System Reset (Type 23) information. + + Routine Description: + Identifies the system-reset capabilities for the system. + Bits 7:6 Reserved for future assignment via this specification, set to 00b. + Bit 5 System contains a watchdog timer, either True (1) or False (0). + Bits 4:3 Boot Option on Limit. + Identifies the system action to be taken when the Reset Limit is reached, one of: + 00b Reserved, do not use. + 01b Operating system + 10b System utilities + 11b Do not rebootBits + 2:1 Boot Option. Indicates the action to be taken following a watchdog reset, one of: + 00b Reserved, do not use. + 01b Operating system + 10b System utilities + 11b Do not reboot + Bit 0 Status. + 1b The system reset is enabled by the user + 0b The system reset is not enabled by the user + + @param[in] Reset Reset + @param[in] Option The option +**/ +VOID +DisplaySystemResetCapabilities ( + IN UINT8 Reset, + IN UINT8 Option + ); + +/** + Display Hardware Security (Type 24) information. + + Routine Description: + Identifies the password and reset status for the system: + + Bits 7:6 Power-on Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown + Bits 5:4 Keyboard Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown + Bits 3:2 Administrator Password Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown + Bits 1:0 Front Panel Reset Status, one of: + 00b Disabled + 01b Enabled + 10b Not Implemented + 11b Unknown + + @param[in] Settings The device settings. + @param[in] Option The device options. +**/ +VOID +DisplayHardwareSecuritySettings ( + IN UINT8 Settings, + IN UINT8 Option + ); + +/** + Display Out-of-Band Remote Access (Type 30) information. + + @param[in] Connections The device characteristics. + @param[in] Option The device options. +**/ +VOID +DisplayOBRAConnections ( + IN UINT8 Connections, + IN UINT8 Option + ); + +/** + Display System Boot Information (Type 32) information. + + @param[in] Parameter The parameter. + @param[in] Option The options. +**/ +VOID +DisplaySystemBootStatus ( + IN UINT8 Parameter, + IN UINT8 Option + ); + +/** + Display System Power Supply (Type 39) information. + + @param[in] Characteristics The device characteristics. + @param[in] Option The device options. +**/ +VOID +DisplaySPSCharacteristics ( + IN UINT16 Characteristics, + IN UINT8 Option + ); + +/** + Display TPM Device (Type 43) Characteristics. + + @param[in] Chara The information bits. + @param[in] Option The optional information. +**/ +VOID +DisplayTpmDeviceCharacteristics ( + IN UINT64 Chara, + IN UINT8 Option + ); + +/** + Display Processor Architecture Type (Type 44). + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorArchitectureType ( + IN UINT8 Key, + IN UINT8 Option + ); +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c new file mode 100644 index 00000000..064bed3d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c @@ -0,0 +1,4836 @@ +/** @file + Build a table, each item is (Key, Info) pair. + And give a interface of query a string out of a table. + + Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2016-2019 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "QueryTable.h" +#include "PrintInfo.h" + +TABLE_ITEM SystemWakeupTypeTable[] = { + { + 0x0, + L" Reserved" + }, + { + 0x1, + L" Other" + }, + { + 0x2, + L" Unknown" + }, + { + 0x3, + L" APM Timer" + }, + { + 0x4, + L" Modem Ring" + }, + { + 0x5, + L" LAN Remote" + }, + { + 0x6, + L" Power Switch" + }, + { + 0x7, + L" AC Power Restored" + } +}; + +TABLE_ITEM BaseBoardFeatureFlagsTable[] = { + { + 0, + L" Hosting board" + }, + { + 1, + L" Requires at least one daughter board or auxiliary card" + }, + { + 2, + L" Removable" + }, + { + 3, + L" Replaceable" + }, + { + 4, + L" Hot swappable" + } +}; + +TABLE_ITEM BaseBoardBoardTypeTable[] = { + { + 0x01, + L" Unknown" + }, + { + 0x02, + L" Other" + }, + { + 0x03, + L" Server Blade" + }, + { + 0x04, + L" Connectivity Switch" + }, + { + 0x05, + L" System Management Module" + }, + { + 0x06, + L" Processor Module" + }, + { + 0x07, + L" I/O Module" + }, + { + 0x08, + L" Memory Module" + }, + { + 0x09, + L" Daughter board" + }, + { + 0x0A, + L" Motherboard" + }, + { + 0x0B, + L" Processor/Memory Module" + }, + { + 0x0C, + L" Processor/IO Module" + }, + { + 0x0D, + L" Interconnect Board" + } +}; + +TABLE_ITEM SystemEnclosureTypeTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Desktop" + }, + { + 0x04, + L" Low Profile Desktop" + }, + { + 0x05, + L" Pizza Box" + }, + { + 0x06, + L" Mini Tower" + }, + { + 0x07, + L" Tower" + }, + { + 0x08, + L" Portable" + }, + { + 0x09, + L" Laptop" + }, + { + 0x0A, + L" Notebook" + }, + { + 0x0B, + L" Hand Held" + }, + { + 0x0C, + L" Docking Station" + }, + { + 0x0D, + L" All in One" + }, + { + 0x0E, + L" Sub Notebook" + }, + { + 0x0F, + L" Space-saving" + }, + { + 0x10, + L" Lunch Box" + }, + { + 0x11, + L" Main Server Chassis" + }, + { + 0x12, + L" Expansion Chassis" + }, + { + 0x13, + L" SubChassis" + }, + { + 0x14, + L" Bus Expansion Chassis" + }, + { + 0x15, + L" Peripheral Chassis" + }, + { + 0x16, + L" RAID Chassis" + }, + { + 0x17, + L" Rack Mount Chassis" + }, + { + 0x18, + L" Sealed-case PC" + }, + { + 0x19, + L" Multi-system Chassis" + }, + { + 0x1A, + L" CompactPCI" + }, + { + 0x1B, + L" AdvancedTCA" + }, + { + 0x1C, + L" Blade" + }, + { + 0x1D, + L" Blade Enclosure" + }, + { + 0x1E, + L" Tablet" + }, + { + 0x1F, + L" Convertible" + }, + { + 0x20, + L" Detachable" + }, + { + 0x21, + L" IoT Gateway" + }, + { + 0x22, + L" Embedded PC" + }, + { + 0x23, + L" Mini PC" + }, + { + 0x24, + L" Stick PC" + }, +}; + +TABLE_ITEM SystemEnclosureStatusTable[] = { + { + 0x1, + L" Other" + }, + { + 0x2, + L" Unknown" + }, + { + 0x3, + L" Safe" + }, + { + 0x4, + L" Warning" + }, + { + 0x5, + L" Critical" + }, + { + 0x6, + L" Non-recoverable" + } +}; + +TABLE_ITEM SESecurityStatusTable[] = { + { + 0x1, + L" Other" + }, + { + 0x2, + L" Unknown" + }, + { + 0x3, + L" None" + }, + { + 0x4, + L" External interface locked out" + }, + { + 0x5, + L" External interface enabled" + } +}; + +TABLE_ITEM ProcessorTypeTable[] = { + { + 0x1, + L" Other" + }, + { + 0x2, + L" Unknown" + }, + { + 0x3, + L" Central Processor" + }, + { + 0x4, + L" Math Processor" + }, + { + 0x5, + L" DSP Processor" + }, + { + 0x6, + L" Video Processor " + }, +}; + +TABLE_ITEM ProcessorUpgradeTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"Daughter Board" + }, + { + 0x04, + L"ZIF Socket" + }, + { + 0x05, + L"Replaceable Piggy Back" + }, + { + 0x06, + L"None" + }, + { + 0x07, + L"LIF Socket" + }, + { + 0x08, + L"Slot 1" + }, + { + 0x09, + L"Slot 2" + }, + { + 0x0A, + L"370-pin socket" + }, + { + 0x0B, + L"Slot A" + }, + { + 0x0C, + L"Slot M" + }, + { + 0x0D, + L"Socket 423" + }, + { + 0x0E, + L"Socket A" + }, + { + 0x0F, + L"Socket 478" + }, + { + 0x10, + L"Socket 754" + }, + { + 0x11, + L"Socket 940" + }, + { + 0x12, + L"Socket 939" + }, + { + 0x13, + L"Socket mPGA604" + }, + { + 0x14, + L"Socket LGA771" + }, + { + 0x15, + L"Socket LGA775" + }, + { + 0x16, + L"Socket S1" + }, + { + 0x17, + L"Socket AM2" + }, + { + 0x18, + L"Socket F" + }, + { + 0x19, + L"Socket LGA1366" + }, + { + 0x1A, + L"Socket G34" + }, + { + 0x1B, + L"Socket AM3" + }, + { + 0x1C, + L"Socket C32" + }, + { + 0x1D, + L"Socket LGA1156" + }, + { + 0x1E, + L"Socket LGA1567" + }, + { + 0x1F, + L"Socket PGA988A" + }, + { + 0x20, + L"Socket BGA1288" + }, + { + 0x21, + L"Socket rPGA988B" + }, + { + 0x22, + L"Socket BGA1023" + }, + { + 0x23, + L"Socket BGA1224" + }, + { + 0x24, + L"Socket LGA1155" + }, + { + 0x25, + L"Socket LGA1356" + }, + { + 0x26, + L"Socket LGA2011" + }, + { + 0x27, + L"Socket FS1" + }, + { + 0x28, + L"Socket FS2" + }, + { + 0x29, + L"Socket FM1" + }, + { + 0x2A, + L"Socket FM2" + }, + { + 0x2B, + L"Socket LGA2011-3" + }, + { + 0x2C, + L"Socket LGA1356-3" + }, + { + 0x2D, + L"Socket LGA1150" + }, + { + 0x2E, + L"Socket BGA1168" + }, + { + 0x2F, + L"Socket BGA1234" + }, + { + 0x30, + L"Socket BGA1364" + }, + { + 0x31, + L"Socket AM4" + }, + { + 0x32, + L"Socket LGA1151" + }, + { + 0x33, + L"Socket BGA1356" + }, + { + 0x34, + L"Socket BGA1440" + }, + { + 0x35, + L"Socket BGA1515" + }, + { + 0x36, + L"Socket LGA3647-1" + }, + { + 0x37, + L"Socket SP3" + }, + { + 0x38, + L"Socket SP3r2" + }, + { + 0x39, + L"Socket LGA2066" + }, + { + 0x3A, + L"Socket BGA1392" + }, + { + 0x3B, + L"Socket BGA1510" + }, + { + 0x3C, + L"Socket BGA1528" + } +}; + +TABLE_ITEM ProcessorCharacteristicsTable[] = { + { + 1, + L" Unknown" + }, + { + 2, + L" 64-bit Capable" + }, + { + 3, + L" Multi-Core" + }, + { + 4, + L" Hardware Thread" + }, + { + 5, + L" Execute Protection" + }, + { + 6, + L" Enhanced Virtualization" + }, + { + 7, + L" Power/Performance Control" + }, + { + 8, + L" 128-bit Capable" + }, + { + 9, + L" ARM64 SoC ID" + } +}; + + +TABLE_ITEM McErrorDetectMethodTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"None" + }, + { + 0x04, + L"8-bit Parity" + }, + { + 0x05, + L"32-bit ECC" + }, + { + 0x06, + L"64-bit ECC" + }, + { + 0x07, + L"128-bit ECC" + }, + { + 0x08, + L"CRC" + }, +}; + +TABLE_ITEM McErrorCorrectCapabilityTable[] = { + { + 0, + L"Other" + }, + { + 1, + L"Unknown" + }, + { + 2, + L"None" + }, + { + 3, + L"Single Bit Error Correcting" + }, + { + 4, + L"Double Bit Error Correcting" + }, + { + 5, + L"Error Scrubbing" + }, +}; + +TABLE_ITEM McInterleaveSupportTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"One Way Interleave" + }, + { + 0x04, + L"Two Way Interleave" + }, + { + 0x05, + L"Four Way Interleave" + }, + { + 0x06, + L"Eight Way Interleave" + }, + { + 0x07, + L"Sixteen Way Interleave" + } +}; + +TABLE_ITEM McMemorySpeedsTable[] = { + { + 0, + L" Other" + }, + { + 1, + L" Unknown" + }, + { + 2, + L" 70ns" + }, + { + 3, + L" 60ns" + }, + { + 4, + L" 50ns" + }, +}; + +TABLE_ITEM MemoryModuleVoltageTable[] = { + { + 0, + L" 5V" + }, + { + 1, + L" 3.3V" + }, + { + 2, + L" 2.9V" + }, +}; + +TABLE_ITEM MmMemoryTypeTable[] = { + { + 0, + L" Other" + }, + { + 1, + L" Unknown" + }, + { + 2, + L" Standard" + }, + { + 3, + L" Fast Page Mode" + }, + { + 4, + L" EDO" + }, + { + 5, + L" Parity" + }, + { + 6, + L" ECC " + }, + { + 7, + L" SIMM" + }, + { + 8, + L" DIMM" + }, + { + 9, + L" Burst EDO" + }, + { + 10, + L" SDRAM" + } +}; + +TABLE_ITEM MmErrorStatusTable[] = { + { + 0, + L" Uncorrectable errors received" + }, + { + 1, + L" Correctable errors received" + }, + { + 2, + L" Error Status obtained from the event log" + } +}; + +TABLE_ITEM CacheSRAMTypeTable[] = { + { + 0, + L" Other" + }, + { + 1, + L" Unknown" + }, + { + 2, + L" Non-Burst" + }, + { + 3, + L" Burst" + }, + { + 4, + L" Pipeline Burst" + }, + { + 5, + L" Synchronous" + }, + { + 6, + L" Asynchronous" + }, +}; + +TABLE_ITEM CacheErrCorrectingTypeTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"None" + }, + { + 0x04, + L"Parity" + }, + { + 0x05, + L"Single-bit ECC" + }, + { + 0x06, + L"Multi-bit ECC" + } +}; + +TABLE_ITEM CacheSystemCacheTypeTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"Instruction" + }, + { + 0x04, + L"Data" + }, + { + 0x05, + L"Unified" + } +}; + +TABLE_ITEM CacheAssociativityTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"Direct Mapped" + }, + { + 0x04, + L"2-way Set-Associative" + }, + { + 0x05, + L"4-way Set-Associative" + }, + { + 0x06, + L"Fully Associative" + }, + { + 0x07, + L"8-way Set-Associative" + }, + { + 0x08, + L"16-way Set-Associative" + }, + { + 0x09, + L"12-way Set-Associative" + }, + { + 0x0A, + L"24-way Set-Associative" + }, + { + 0x0B, + L"32-way Set-Associative" + }, + { + 0x0C, + L"48-way Set-Associative" + }, + { + 0x0D, + L"64-way Set-Associative" + }, + { + 0x0E, + L"20-way Set-Associative" + } +}; + +TABLE_ITEM PortConnectorTypeTable[] = { + { + 0x00, + L"None" + }, + { + 0x01, + L"Centronics" + }, + { + 0x02, + L"Mini Centronics" + }, + { + 0x03, + L"Proprietary" + }, + { + 0x04, + L"DB-25 pin male" + }, + { + 0x05, + L"DB-25 pin female" + }, + { + 0x06, + L"DB-15 pin male" + }, + { + 0x07, + L"DB-15 pin female" + }, + { + 0x08, + L"DB-9 pin male" + }, + { + 0x09, + L"DB-9 pin female" + }, + { + 0x0A, + L"RJ-11" + }, + { + 0x0B, + L"RJ-45" + }, + { + 0x0C, + L"50 Pin MiniSCSI" + }, + { + 0x0D, + L"Mini-DIN" + }, + { + 0x0E, + L"Micro-DIN" + }, + { + 0x0F, + L"PS/2" + }, + { + 0x10, + L"Infrared" + }, + { + 0x11, + L"HP-HIL" + }, + { + 0x12, + L"Access Bus (USB)" + }, + { + 0x13, + L"SSA SCSI" + }, + { + 0x14, + L"Circular DIN-8 male" + }, + { + 0x15, + L"Circular DIN-8 female" + }, + { + 0x16, + L"On Board IDE" + }, + { + 0x17, + L"On Board Floppy" + }, + { + 0x18, + L"9 Pin Dual Inline (pin 10 cut)" + }, + { + 0x19, + L"25 Pin Dual Inline (pin 26 cut)" + }, + { + 0x1A, + L"50 Pin Dual Inline" + }, + { + 0x1B, + L"68 Pin Dual Inline" + }, + { + 0x1C, + L"On Board Sound Input from CD-ROM" + }, + { + 0x1D, + L"Mini-Centronics Type-14" + }, + { + 0x1E, + L"Mini-Centronics Type-26" + }, + { + 0x1F, + L"Mini-jack (headphones)" + }, + { + 0x20, + L"BNC" + }, + { + 0x21, + L"1394" + }, + { + 0x22, + L"SAS/SATA Plug Receptacle" + }, + { + 0x23, + L"USB Type-C Receptacle" + }, + { + 0xA0, + L"PC-98" + }, + { + 0xA1, + L"PC-98Hireso" + }, + { + 0xA2, + L"PC-H98" + }, + { + 0xA3, + L"PC-98Note" + }, + { + 0xA4, + L"PC-98Full" + }, + { + 0xFF, + L"Other" + }, +}; + +TABLE_ITEM PortTypeTable[] = { + { + 0x00, + L"None" + }, + { + 0x01, + L"Parallel Port XT/AT Compatible" + }, + { + 0x02, + L"Parallel Port PS/2" + }, + { + 0x03, + L"Parallel Port ECP" + }, + { + 0x04, + L"Parallel Port EPP" + }, + { + 0x05, + L"Parallel Port ECP/EPP" + }, + { + 0x06, + L"Serial Port XT/AT Compatible" + }, + { + 0x07, + L"Serial Port 16450 Compatible" + }, + { + 0x08, + L"Serial Port 16550 Compatible" + }, + { + 0x09, + L"Serial Port 16550A Compatible" + }, + { + 0x0A, + L"SCSI Port" + }, + { + 0x0B, + L"MIDI Port" + }, + { + 0x0C, + L"Joy Stick Port" + }, + { + 0x0D, + L"Keyboard Port" + }, + { + 0x0E, + L"Mouse Port" + }, + { + 0x0F, + L"SSA SCSI" + }, + { + 0x10, + L"USB" + }, + { + 0x11, + L"FireWire (IEEE P1394)" + }, + { + 0x12, + L"PCMCIA Type II" + }, + { + 0x13, + L"PCMCIA Type II" + }, + { + 0x14, + L"PCMCIA Type III" + }, + { + 0x15, + L"Cardbus" + }, + { + 0x16, + L"Access Bus Port" + }, + { + 0x17, + L"SCSI II" + }, + { + 0x18, + L"SCSI Wide" + }, + { + 0x19, + L"PC-98" + }, + { + 0x1A, + L"PC-98-Hireso" + }, + { + 0x1B, + L"PC-H98" + }, + { + 0x1C, + L"Video Port" + }, + { + 0x1D, + L"Audio Port" + }, + { + 0x1E, + L"Modem Port" + }, + { + 0x1F, + L"Network Port" + }, + { + 0x20, + L"SATA Port" + }, + { + 0x21, + L"SAS Port" + }, + { + 0x22, + L"Multi-Function Display Port (MFDP)" + }, + { + 0x23, + L"Thunderbolt" + }, + { + 0xA0, + L"8251 Compatible" + }, + { + 0xA1, + L"8251 FIFO Compatible" + }, + { + 0xFF, + L"Other " + }, +}; + +TABLE_ITEM SystemSlotTypeTable[] = { + { + 0x01, + L"Other" + }, + { + 0x02, + L"Unknown" + }, + { + 0x03, + L"ISA" + }, + { + 0x04, + L"MCA" + }, + { + 0x05, + L"EISA" + }, + { + 0x06, + L"PCI" + }, + { + 0x07, + L"PC Card (PCMCIA)" + }, + { + 0x08, + L"VL-VESA" + }, + { + 0x09, + L"Proprietary" + }, + { + 0x0A, + L"Processor Card Slot" + }, + { + 0x0B, + L"Proprietary Memory Card Slot" + }, + { + 0x0C, + L"I/O Riser Card Slot" + }, + { + 0x0D, + L"NuBus" + }, + { + 0x0E, + L"PCI - 66MHz Capable" + }, + { + 0x0F, + L"AGP" + }, + { + 0x10, + L"AGP 2X" + }, + { + 0x11, + L"AGP 4X" + }, + { + 0x12, + L"PCI-X" + }, + { + 0x13, + L"AGP 8X" + }, + { + 0x14, + L"M.2 Socket 1-DP (Mechanical Key A)" + }, + { + 0x15, + L"M.2 Socket 1-SD (Mechanical Key E)" + }, + { + 0x16, + L"M.2 Socket 2 (Mechanical Key B)" + }, + { + 0x17, + L"M.2 Socket 3 (Mechanical Key M)" + }, + { + 0x18, + L"MXM Type I" + }, + { + 0x19, + L"MXM Type II" + }, + { + 0x1A, + L"MXM Type III (standard connector)" + }, + { + 0x1B, + L"MXM Type III (HE connector)" + }, + { + 0x1C, + L"MXM Type IV" + }, + { + 0x1D, + L"MXM 3.0 Type A" + }, + { + 0x1E, + L"MXM 3.0 Type B" + }, + { + 0x1F, + L"PCI Express Gen 2 SFF-8639" + }, + { + 0x20, + L"PCI Express Gen 3 SFF-8639" + }, + { + 0x21, + L"PCI Express Mini 52-pin (CEM spec. 2.0) with bottom-side keep-outs" + }, + { + 0x22, + L"PCI Express Mini 52-pin (CEM spec. 2.0) without bottom-side keep-outs" + }, + { + 0x23, + L"PCI Express Mini 76-pin (CEM spec. 2.0) Corresponds to Display-Mini card" + }, + { + SlotTypeCXLFlexbus10, + L"CXL Flexbus 1.0" + }, + { + 0xA0, + L"PC-98/C20 " + }, + { + 0xA1, + L"PC-98/C24 " + }, + { + 0xA2, + L"PC-98/E " + }, + { + 0xA3, + L"PC-98/Local Bus " + }, + { + 0xA4, + L"PC-98/Card " + }, + { + 0xA5, + L"PCI Express " + }, + { + 0xA6, + L"PCI Express X1" + }, + { + 0xA7, + L"PCI Express X2" + }, + { + 0xA8, + L"PCI Express X4" + }, + { + 0xA9, + L"PCI Express X8" + }, + { + 0xAA, + L"PCI Express X16" + }, + { + 0xAB, + L"PCI Express Gen 2" + }, + { + 0xAC, + L"PCI Express Gen 2 X1" + }, + { + 0xAD, + L"PCI Express Gen 2 X2" + }, + { + 0xAE, + L"PCI Express Gen 2 X4" + }, + { + 0xAF, + L"PCI Express Gen 2 X8" + }, + { + 0xB0, + L"PCI Express Gen 2 X16" + }, + { + 0xB1, + L"PCI Express Gen 3" + }, + { + 0xB2, + L"PCI Express Gen 3 X1" + }, + { + 0xB3, + L"PCI Express Gen 3 X2" + }, + { + 0xB4, + L"PCI Express Gen 3 X4" + }, + { + 0xB5, + L"PCI Express Gen 3 X8" + }, + { + 0xB6, + L"PCI Express Gen 3 X16" + }, + { + SlotTypePciExpressGen4, + L"PCI Express Gen 4" + }, + { + SlotTypePciExpressGen4X1, + L"PCI Express Gen 4 X1" + }, + { + SlotTypePciExpressGen4X2, + L"PCI Express Gen 4 X2" + }, + { + SlotTypePciExpressGen4X4, + L"PCI Express Gen 4 X4" + }, + { + SlotTypePciExpressGen4X8, + L"PCI Express Gen 4 X8" + }, + { + SlotTypePciExpressGen4X16, + L"PCI Express Gen 4 X16" + } +}; + +TABLE_ITEM SystemSlotDataBusWidthTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" 8 bit" + }, + { + 0x04, + L" 16 bit" + }, + { + 0x05, + L" 32 bit" + }, + { + 0x06, + L" 64 bit" + }, + { + 0x07, + L" 128 bit" + }, + { + 0x08, + L" 1x or x1" + }, + { + 0x09, + L" 2x or x2" + }, + { + 0x0A, + L" 4x or x4" + }, + { + 0x0B, + L" 8x or x8" + }, + { + 0x0C, + L" 12x or x12" + }, + { + 0x0D, + L" 16x or x16" + }, + { + 0x0E, + L" 32x or x32" + } +}; + +TABLE_ITEM SystemSlotCurrentUsageTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Available" + }, + { + 0x04, + L" In use" + }, + { + 0x05, + L" Unavailable" + } +}; + +TABLE_ITEM SystemSlotLengthTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Short length" + }, + { + 0x04, + L" Long Length" + }, +}; + +TABLE_ITEM SlotCharacteristics1Table[] = { + { + 0, + L" Characteristics Unknown" + }, + { + 1, + L" Provides 5.0 Volts" + }, + { + 2, + L" Provides 3.3 Volts" + }, + { + 3, + L" Slot's opening is shared with another slot, e.g. PCI/EISA shared slot." + }, + + { + 4, + L" PC Card slot supports PC Card-16" + }, + { + 5, + L" PC Card slot supports CardBus" + }, + { + 6, + L" PC Card slot supports Zoom Video " + }, + { + 7, + L" PC Card slot supports Modem Ring Resume " + } +}; + +TABLE_ITEM SlotCharacteristics2Table[] = { + { + 0, + L" PCI slot supports Power Management Enable (PME#) signal" + }, + { + 1, + L" Slot supports hot-plug devices" + }, + { + 2, + L" PCI slot supports SMBus signal" + }, + { + 3, + L" PCIe slot supports bifurcation" + } +}; + +TABLE_ITEM OnboardDeviceTypesTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Video" + }, + { + 0x04, + L" SCSI Controller" + }, + { + 0x05, + L" Ethernet" + }, + { + 0x06, + L" Token Ring" + }, + { + 0x07, + L" Sound" + }, + { + 0x08, + L" Pata Controller" + }, + { + 0x09, + L" Sata Controller" + }, + { + 0x0A, + L" Sas Controller" + }, +}; + +TABLE_ITEM SELTypesTable[] = { + { + 0x00, + L" Reserved." + }, + { + 0x01, + L" Single-bit ECC memory error" + }, + { + 0x02, + L" Multi-bit ECC memory error" + }, + { + 0x03, + L" Parity memory error" + }, + { + 0x04, + L" Bus time-out" + }, + { + 0x05, + L" I/O Channel Check" + }, + { + 0x06, + L" Software NMI" + }, + { + 0x07, + L" POST Memory Resize" + }, + { + 0x08, + L" POST Error" + }, + { + 0x09, + L" PCI Parity Error" + }, + { + 0x0A, + L" PCI System Error" + }, + { + 0x0B, + L" CPU Failure" + }, + { + 0x0C, + L" EISA FailSafe Timer time-out" + }, + { + 0x0D, + L" Correctable memory log disabled" + }, + { + 0x0E, + L" Logging disabled for a specific Event Type" + }, + { + 0x0F, + L" Reserved" + }, + { + 0x10, + L" System Limit Exceeded" + }, + { + 0x11, + L" Asynchronous hardware timer expired and issued a system reset" + }, + { + 0x12, + L" System configuration information" + }, + { + 0x13, + L" Hard-disk information" + }, + { + 0x14, + L" System reconfigured" + }, + { + 0x15, + L" Uncorrectable CPU-complex error" + }, + { + 0x16, + L" Log Area Reset/Cleared" + }, + { + 0x17, + L" System boot" + }, + { + 0x7F18, + L" Unused by SMBIOS specification" + }, + { + 0xFE80, + L" System and OEM specified" + }, + { + 0xFF, + L" End-of-log" + }, +}; + +TABLE_ITEM SELVarDataFormatTypeTable[] = { + { + 0x00, + L" None " + }, + { + 0x01, + L" Handle " + }, + { + 0x02, + L" Multiple-Event " + }, + { + 0x03, + L" Multiple-Event Handle " + }, + { + 0x04, + L" POST Results Bitmap " + }, + // + // Defined below + // + { + 0x05, + L" System Management Type" + }, + // + // Defined below + // + { + 0x06, + L" Multiple-Event System Management Type " + }, + { + 0x7F07, + L" Unused " + }, + { + 0xFF80, + L" OEM assigned " + }, +}; + +TABLE_ITEM PostResultsBitmapDw1Table[] = { + { + 0, + L" Channel 2 Timer error " + }, + { + 1, + L" Master PIC (8259 #1) error " + }, + { + 2, + L" Slave PIC (8259 #2) error " + }, + { + 3, + L" CMOS Battery Failure " + }, + { + 4, + L" CMOS System Options Not Set " + }, + { + 5, + L" CMOS Checksum Error " + }, + { + 6, + L" CMOS Configuration Error " + }, + { + 7, + L" Mouse and Keyboard Swapped " + }, + { + 8, + L" Keyboard Locked " + }, + { + 9, + L" Keyboard Not Functional " + }, + { + 10, + L" Keyboard Controller Not Functional " + }, + { + 11, + L" CMOS Memory Size Different " + }, + { + 12, + L" Memory Decreased in Size " + }, + { + 13, + L" Cache Memory Error " + }, + { + 14, + L" Floppy Drive 0 Error " + }, + { + 15, + L" Floppy Drive 1 Error " + }, + { + 16, + L" Floppy Controller Failure " + }, + { + 17, + L" Number of ATA Drives Reduced Error " + }, + { + 18, + L" CMOS Time Not Set " + }, + { + 19, + L" DDC Monitor Configuration Change " + }, + { + 20, + L" Reserved, set to 0 " + }, + { + 21, + L" Reserved, set to 0 " + }, + { + 22, + L" Reserved, set to 0 " + }, + { + 23, + L" Reserved, set to 0 " + }, + { + 24, + L" Second DWORD has valid data " + }, + { + 25, + L" Reserved, set to 0 " + }, + { + 26, + L" Reserved, set to 0 " + }, + { + 27, + L" Reserved, set to 0 " + }, + { + 28, + L" Normally 0; available for OEM assignment " + }, + { + 29, + L" Normally 0; available for OEM assignment " + }, + { + 30, + L" Normally 0; available for OEM assignment " + }, + { + 31, + L" Normally 0; available for OEM assignment " + }, +}; + +TABLE_ITEM PostResultsBitmapDw2Table[] = { + { + 0, + L" Normally 0; available for OEM assignment " + }, + { + 1, + L" Normally 0; available for OEM assignment " + }, + { + 2, + L" Normally 0; available for OEM assignment " + }, + { + 3, + L" Normally 0; available for OEM assignment " + }, + { + 4, + L" Normally 0; available for OEM assignment " + }, + { + 5, + L" Normally 0; available for OEM assignment " + }, + { + 6, + L" Normally 0; available for OEM assignment " + }, + { + 7, + L" PCI Memory Conflict " + }, + { + 8, + L" PCI I/O Conflict " + }, + { + 9, + L" PCI IRQ Conflict " + }, + { + 10, + L" PNP Memory Conflict " + }, + { + 11, + L" PNP 32 bit Memory Conflict " + }, + { + 12, + L" PNP I/O Conflict " + }, + { + 13, + L" PNP IRQ Conflict " + }, + { + 14, + L" PNP DMA Conflict " + }, + { + 15, + L" Bad PNP Serial ID Checksum " + }, + { + 16, + L" Bad PNP Resource Data Checksum " + }, + { + 17, + L" Static Resource Conflict " + }, + { + 18, + L" NVRAM Checksum Error, NVRAM Cleared " + }, + { + 19, + L" System Board Device Resource Conflict " + }, + { + 20, + L" Primary Output Device Not Found " + }, + { + 21, + L" Primary Input Device Not Found " + }, + { + 22, + L" Primary Boot Device Not Found " + }, + { + 23, + L" NVRAM Cleared By Jumper " + }, + { + 24, + L" NVRAM Data Invalid, NVRAM Cleared " + }, + { + 25, + L" FDC Resource Conflict " + }, + { + 26, + L" Primary ATA Controller Resource Conflict " + }, + { + 27, + L" Secondary ATA Controller Resource Conflict " + }, + { + 28, + L" Parallel Port Resource Conflict " + }, + { + 29, + L" Serial Port 1 Resource Conflict " + }, + { + 30, + L" Serial Port 2 Resource Conflict " + }, + { + 31, + L" Audio Resource Conflict " + }, +}; + +TABLE_ITEM SELSysManagementTypesTable[] = { + { + 0x01, + L" +2.5V Out of range, #2 " + }, + { + 0x02, + L" +3.3V Out of range " + }, + { + 0x03, + L" +5V Out of range " + }, + { + 0x04, + L" -5V Out of range " + }, + { + 0x05, + L" +12V Out of range " + }, + { + 0x06, + L" -12V Out of range " + }, + { + 0x0F07, + L" Reserved for future out-of-range voltage levels " + }, + { + 0x10, + L" System board temperature out of range " + }, + { + 0x11, + L" Processor #1 temperature out of range " + }, + { + 0x12, + L" Processor #2 temperature out of range " + }, + { + 0x13, + L" Processor #3 temperature out of range " + }, + { + 0x14, + L" Processor #4 temperature out of range " + }, + { + 0x1F15, + L" Reserved for future out-of-range temperatures" + }, + { + 0x2720, + L" Fan n (n = 0 to 7) Out of range " + }, + { + 0x2F28, + L" Reserved for future assignment via this specification " + }, + { + 0x30, + L" Chassis secure switch activated " + }, +}; + +TABLE_ITEM PMALocationTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" System board or motherboard" + }, + { + 0x04, + L" ISA add-on card" + }, + { + 0x05, + L" EISA add-on card" + }, + { + 0x06, + L" PCI add-on card" + }, + { + 0x07, + L" MCA add-on card" + }, + { + 0x08, + L" PCMCIA add-on card" + }, + { + 0x09, + L" Proprietary add-on card" + }, + { + 0x0A, + L" NuBus" + }, + { + 0xA0, + L" PC-98/C20 add-on card" + }, + { + 0xA1, + L" PC-98/C24 add-on card" + }, + { + 0xA2, + L" PC-98/E add-on card" + }, + { + 0xA3, + L" PC-98/Local bus add-on card" + }, + { + MemoryArrayLocationCXLFlexbus10AddonCard, + L" CXL Flexbus 1.0 add-on card" + } +}; + +TABLE_ITEM PMAUseTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" System memory" + }, + { + 0x04, + L" Video memory" + }, + { + 0x05, + L" Flash memory" + }, + { + 0x06, + L" Non-volatile RAM" + }, + { + 0x07, + L" Cache memory" + } +}; + +TABLE_ITEM PMAErrorCorrectionTypesTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" None" + }, + { + 0x04, + L" Parity" + }, + { + 0x05, + L" Single-bit ECC" + }, + { + 0x06, + L" Multi-bit ECC" + }, + { + 0x07, + L" CRC" + } +}; + +TABLE_ITEM MemoryDeviceFormFactorTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" SIMM" + }, + { + 0x04, + L" SIP" + }, + { + 0x05, + L" Chip" + }, + { + 0x06, + L" DIP" + }, + { + 0x07, + L" ZIP" + }, + { + 0x08, + L" Proprietary Card" + }, + { + 0x09, + L" DIMM" + }, + { + 0x0A, + L" TSOP" + }, + { + 0x0B, + L" Row of chips" + }, + { + 0x0C, + L" RIMM" + }, + { + 0x0D, + L" SODIMM" + }, + { + 0x0E, + L" SRIMM" + }, + { + 0x0F, + L" FB-DIMM" + }, + { + MemoryFormFactorDie, + L" Die" + } +}; + +TABLE_ITEM MemoryDeviceTypeTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" DRAM" + }, + { + 0x04, + L" EDRAM" + }, + { + 0x05, + L" VRAM" + }, + { + 0x06, + L" SRAM" + }, + { + 0x07, + L" RAM" + }, + { + 0x08, + L" ROM" + }, + { + 0x09, + L" FLASH" + }, + { + 0x0A, + L" EEPROM" + }, + { + 0x0B, + L" FEPROM" + }, + { + 0x0C, + L" EPROM" + }, + { + 0x0D, + L" CDRAM" + }, + { + 0x0E, + L" 3DRAM" + }, + { + 0x0F, + L" SDRAM" + }, + { + 0x10, + L" SGRAM" + }, + { + 0x11, + L" RDRAM" + }, + { + 0x12, + L" DDR" + }, + { + 0x13, + L" DDR2" + }, + { + 0x14, + L" DDR2 FB-DIMM" + }, + { + 0x18, + L" DDR3" + }, + { + 0x19, + L" FBD2" + }, + { + 0x1A, + L" DDR4" + }, + { + 0x1B, + L" LPDDR" + }, + { + 0x1C, + L" LPDDR2" + }, + { + 0x1D, + L" LPDDR3" + }, + { + 0x1E, + L" LPDDR4" + }, + { + 0x1F, + L" Logical non-volatile device" + }, + { + MemoryTypeHBM, + L" HBM (High Bandwidth Memory)" + }, + { + MemoryTypeHBM2, + L" HBM2 (High Bandwidth Memory Generation 2)" + }, + { + MemoryTypeDdr5, + L" DDR5" + }, + { + MemoryTypeLpddr5, + L" LPDDR5" + } +}; + +TABLE_ITEM MemoryDeviceTypeDetailTable[] = { + { + 1, + L" Other" + }, + { + 2, + L" Unknown" + }, + { + 3, + L" Fast-paged" + }, + { + 4, + L" Static column" + }, + { + 5, + L" Pseudo-STATIC" + }, + { + 6, + L" RAMBUS " + }, + { + 7, + L" Synchronous" + }, + { + 8, + L" CMOS" + }, + { + 9, + L" EDO" + }, + { + 10, + L" Window DRAM" + }, + { + 11, + L" Cache DRAM" + }, + { + 12, + L" Non-volatile" + }, + { + 13, + L" Registered(Buffered)" + }, + { + 14, + L" Unbuffered(Unregistered)" + } +}; + +TABLE_ITEM MemoryDeviceMemoryTechnologyTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" DRAM" + }, + { + 0x04, + L" NVDIMM-N" + }, + { + 0x05, + L" NVDIMM-F" + }, + { + 0x06, + L" NVDIMM-P" + }, + { + MemoryTechnologyIntelPersistentMemory, + L" Intel Optane DC Persistent Memory" + } +}; + +TABLE_ITEM MemoryDeviceMemoryOperatingModeCapabilityTable[] = { + { + 1, + L" Other" + }, + { + 2, + L" Unknown" + }, + { + 3, + L" Volatile memory" + }, + { + 4, + L" Byte-accessible persistent memory" + }, + { + 5, + L" Block-accessible persistent memory" + } +}; + + +TABLE_ITEM MemoryErrorTypeTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" OK" + }, + { + 0x04, + L" Bad read" + }, + { + 0x05, + L" Parity error" + }, + { + 0x06, + L" Single-bit error" + }, + { + 0x07, + L" Double-bit error" + }, + { + 0x08, + L" Multi-bit error" + }, + { + 0x09, + L" Nibble error" + }, + { + 0x0A, + L" Checksum error" + }, + { + 0x0B, + L" CRC error" + }, + { + 0x0C, + L" Corrected single-bit error" + }, + { + 0x0D, + L" Corrected error" + }, + { + 0x0E, + L" Uncorrectable error" + }, +}; + +TABLE_ITEM MemoryErrorGranularityTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Device level" + }, + { + 0x04, + L" Memory partition level" + }, +}; + +TABLE_ITEM MemoryErrorOperationTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Read" + }, + { + 0x04, + L" Write" + }, + { + 0x05, + L" Partial Write" + }, +}; + +TABLE_ITEM PointingDeviceTypeTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Mouse" + }, + { + 0x04, + L" Track Ball" + }, + { + 0x05, + L" Track Point" + }, + { + 0x06, + L" Glide Point" + }, + { + 0x07, + L" Touch Pad" + }, +}; + +TABLE_ITEM PointingDeviceInterfaceTable[] = { + { + 0x01, + L" Other" + }, + { + 0x02, + L" Unknown" + }, + { + 0x03, + L" Serial" + }, + { + 0x04, + L" PS/2" + }, + { + 0x05, + L" Infrared" + }, + { + 0x06, + L" HP-HIL" + }, + { + 0x07, + L" Bus mouse" + }, + { + 0x08, + L" ADB(Apple Desktop Bus" + }, + { + 0xA0, + L" Bus mouse DB-9" + }, + { + 0xA1, + L" Bus mouse mirco-DIN" + }, + { + 0xA2, + L" USB" + }, +}; + +TABLE_ITEM PBDeviceChemistryTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" Lead Acid " + }, + { + 0x04, + L" Nickel Cadmium " + }, + { + 0x05, + L" Nickel metal hydride " + }, + { + 0x06, + L" Lithium-ion " + }, + { + 0x07, + L" Zinc air " + }, + { + 0x08, + L" Lithium Polymer " + }, +}; + +TABLE_ITEM VPLocationTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" OK " + }, + { + 0x04, + L" Non-critical " + }, + { + 0x05, + L" Critical " + }, + { + 0x06, + L" Non-recoverable " + }, +}; + +TABLE_ITEM VPStatusTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" Processor " + }, + { + 0x04, + L" Disk " + }, + { + 0x05, + L" Peripheral Bay " + }, + { + 0x06, + L" System Management Module " + }, + { + 0x07, + L" Motherboard " + }, + { + 0x08, + L" Memory Module " + }, + { + 0x09, + L" Processor Module " + }, + { + 0x0A, + L" Power Unit " + }, + { + 0x0B, + L" Add-in Card " + }, +}; + +TABLE_ITEM CoolingDeviceStatusTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" OK " + }, + { + 0x04, + L" Non-critical " + }, + { + 0x05, + L" Critical " + }, + { + 0x06, + L" Non-recoverable " + }, +}; + +TABLE_ITEM CoolingDeviceTypeTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" Fan " + }, + { + 0x04, + L" Centrifugal Blower " + }, + { + 0x05, + L" Chip Fan " + }, + { + 0x06, + L" Cabinet Fan " + }, + { + 0x07, + L" Power Supply Fan " + }, + { + 0x08, + L" Heat Pipe " + }, + { + 0x09, + L" Integrated Refrigeration " + }, + { + 0x10, + L" Active Cooling " + }, + { + 0x11, + L" Passive Cooling " + }, +}; + +TABLE_ITEM TemperatureProbeStatusTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" OK " + }, + { + 0x04, + L" Non-critical " + }, + { + 0x05, + L" Critical " + }, + { + 0x06, + L" Non-recoverable " + }, +}; + +TABLE_ITEM TemperatureProbeLocTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" Processor " + }, + { + 0x04, + L" Disk " + }, + { + 0x05, + L" Peripheral Bay " + }, + { + 0x06, + L" System Management Module " + }, + { + 0x07, + L" Motherboard " + }, + { + 0x08, + L" Memory Module " + }, + { + 0x09, + L" Processor Module " + }, + { + 0x0A, + L" Power Unit " + }, + { + 0x0B, + L" Add-in Card " + }, +}; + +TABLE_ITEM ECPStatusTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" OK " + }, + { + 0x04, + L" Non-critical " + }, + { + 0x05, + L" Critical " + }, + { + 0x06, + L" Non-recoverable " + }, +}; + +TABLE_ITEM ECPLocTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" Processor " + }, + { + 0x04, + L" Disk " + }, + { + 0x05, + L" Peripheral Bay " + }, + { + 0x06, + L" System Management Module " + }, + { + 0x07, + L" Motherboard " + }, + { + 0x08, + L" Memory Module " + }, + { + 0x09, + L" Processor Module " + }, + { + 0x0A, + L" Power Unit " + }, + { + 0x0B, + L" Add-in Card " + }, +}; + +TABLE_ITEM MDTypeTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" National Semiconductor LM75 " + }, + { + 0x04, + L" National Semiconductor LM78 " + }, + { + 0x05, + L" National Semiconductor LM79 " + }, + { + 0x06, + L" National Semiconductor LM80 " + }, + { + 0x07, + L" National Semiconductor LM81 " + }, + { + 0x08, + L" Analog Devices ADM9240 " + }, + { + 0x09, + L" Dallas Semiconductor DS1780 " + }, + { + 0x0A, + L" Maxim 1617 " + }, + { + 0x0B, + L" Genesys GL518SM " + }, + { + 0x0C, + L" Winbond W83781D " + }, + { + 0x0D, + L" Holtek HT82H791 " + }, +}; + +TABLE_ITEM MDAddressTypeTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" I/O Port " + }, + { + 0x04, + L" Memory " + }, + { + 0x05, + L" SM Bus " + }, +}; + +TABLE_ITEM MemoryChannelTypeTable[] = { + { + 0x01, + L" Other " + }, + { + 0x02, + L" Unknown " + }, + { + 0x03, + L" RamBus " + }, + { + 0x04, + L" SyncLink " + }, +}; + +TABLE_ITEM IPMIDIBMCInterfaceTypeTable[] = { + { + 0x00, + L" Unknown " + }, + { + 0x01, + L" KCS: Keyboard Controller Style " + }, + { + 0x02, + L" SMIC: Server Management Interface Chip " + }, + { + 0x03, + L" BT: Block Transfer " + }, + { + 0x04, + L" SSIF: SMBus System Interface " + }, + { + 0xFF05, + L" Reserved for future assignment by this specification " + }, +}; + +TABLE_ITEM MCHostInterfaceTypeTable[] = { + { + 0x3F00, + L" MCTP Host Interface " + }, + { + 0x40, + L" Network Host Interface " + }, + { + 0xF0, + L" OEM defined " + }, +}; + +TABLE_ITEM ProcessorArchitectureTypesTable[] = { + { + 0, + L" Reserved " + }, + { + 1, + L" IA32 (x86) " + }, + { + 2, + L" x64 (x86-64, intel64, AMD64, EM64T) " + }, + { + 3, + L" Intel Itanium architecture " + }, + { + 4, + L" 32-bit ARM (Aarch32) " + }, + { + 5, + L" 64-bit ARM (Aarch64) " + }, + { + 6, + L" 32-bit RISC-V (RV32) " + }, + { + 7, + L" 64-bit RISC-V (RV64) " + }, + { + 8, + L" 128-bit RISC-V (RV128) " + } +}; + +TABLE_ITEM StructureTypeInfoTable[] = { + { + 0, + L" BIOS Information" + }, + { + 1, + L" System Information" + }, + { + 2, + L" Base Board Information" + }, + { + 3, + L" System Enclosure" + }, + { + 4, + L" Processor Information" + }, + { + 5, + L" Memory Controller Information " + }, + { + 6, + L" Memory Module Information " + }, + { + 7, + L" Cache Information " + }, + { + 8, + L" Port Connector Information " + }, + { + 9, + L" System Slots " + }, + { + 10, + L" On Board Devices Information " + }, + { + 11, + L" OEM Strings" + }, + { + 12, + L" System Configuration Options " + }, + { + 13, + L" BIOS Language Information " + }, + { + 14, + L" Group Associations " + }, + { + 15, + L" System Event Log " + }, + { + 16, + L" Physical Memory Array " + }, + { + 17, + L" Memory Device " + }, + { + 18, + L" 32-bit Memory Error Information " + }, + { + 19, + L" Memory Array Mapped Address " + }, + { + 20, + L" Memory Device Mapped Address " + }, + { + 21, + L" Built-in Pointing Device " + }, + { + 22, + L" Portable Battery " + }, + { + 23, + L" System Reset " + }, + { + 24, + L" Hardware Security " + }, + { + 25, + L" System Power Controls " + }, + { + 26, + L" Voltage Probe " + }, + { + 27, + L" Cooling Device " + }, + { + 28, + L" Temperature Probe " + }, + { + 29, + L" Electrical Current Probe " + }, + { + 30, + L" Out-of-Band Remote Access " + }, + { + 31, + L" Boot Integrity Services (BIS) Entry Point" + }, + { + 32, + L" System Boot Information " + }, + { + 33, + L" 64-bit Memory Error Information " + }, + { + 34, + L" Management Device " + }, + { + 35, + L" Management Device Component " + }, + { + 36, + L" Management Device Threshold Data " + }, + { + 37, + L" Memory Channel " + }, + { + 38, + L" IPMI Device Information " + }, + { + 39, + L" System Power Supply" + }, + { + 40, + L" Additional Information" + }, + { + 41, + L" Onboard Devices Extended Information" + }, + { + 42, + L" Management Controller Host Interface" + }, + { + 43, + L" TPM Device" + }, + { + 44, + L" Processor Additional Information" + }, + { + 0x7E, + L" Inactive" + }, + { + 0x7F, + L" End-of-Table " + }, +}; + + +/** + Given a table and a Key, return the responding info. + + Notes: + Table[Index].Key is change from UINT8 to UINT16, + in order to deal with "0xaa - 0xbb". + + For example: + DisplaySELVariableDataFormatTypes(UINT8 Type, UINT8 Option) + has a item: + "0x07-0x7F, Unused" + Now define Key = 0x7F07, that is to say: High = 0x7F, Low = 0x07. + Then all the Key Value between Low and High gets the same string + L"Unused". + + @param[in] Table The begin address of table. + @param[in] Number The number of table items. + @param[in] Key The query Key. + @param[in, out] Info Input as empty buffer; output as data buffer. + @param[in] InfoLen The max number of characters for Info. + + @return the found Key and Info is valid. + @retval QUERY_TABLE_UNFOUND and Info should be NULL. +**/ +UINT8 +QueryTable ( + IN TABLE_ITEM *Table, + IN UINTN Number, + IN UINT8 Key, + IN OUT CHAR16 *Info, + IN UINTN InfoLen + ) +{ + UINTN Index; + // + // High byte and Low byte of word + // + UINT8 High; + UINT8 Low; + + for (Index = 0; Index < Number; Index++) { + High = (UINT8) (Table[Index].Key >> 8); + Low = (UINT8) (Table[Index].Key & 0x00FF); + + // + // Check if Key is in the range + // or if Key == Value in the table + // + if ((High > Low && Key >= Low && Key <= High) + || (Table[Index].Key == Key)) { + StrnCpyS (Info, InfoLen, Table[Index].Info, InfoLen - 1); + StrnCatS (Info, InfoLen, L"\n", InfoLen - 1 - StrLen(Info)); + return Key; + } + } + + StrCpyS (Info, InfoLen, L"Undefined Value\n"); + return QUERY_TABLE_UNFOUND; +} + +/** + Given a table of bit info and a Key, return the responding info to the Key. + + @param[in] Table Point to a table which maintains a map of 'bit' to 'message'. + @param[in] Number Number of table items. + @param[in] Bits The Key of query the bit map information. +**/ +VOID +PrintBitsInfo ( + IN TABLE_ITEM *Table, + IN UINTN Number, + IN UINT32 Bits + ) +{ + // + // Get certain bit of 'Value': + // +#define BIT(Value, bit) ((Value) & ((UINT32) 1) << (bit)) + // + // Clear certain bit of 'Value': + // +#define CLR_BIT(Value, bit) ((Value) -= (BIT (Value, bit))) + + UINTN Index; + UINT32 Value; + BOOLEAN FirstInfo; + + FirstInfo = TRUE; + Value = Bits; + // + // query the table and print information + // + for (Index = 0; Index < Number; Index++) { + if (BIT (Value, Table[Index].Key) != 0) { + if (!FirstInfo) { + // + // If it is not first info, print the separator first. + // + Print (L" | "); + } + Print (Table[Index].Info); + + FirstInfo = FALSE; + // + // clear the bit, for reserved bits test + // + CLR_BIT (Value, Table[Index].Key); + } + } + + // + // There is no any info if FirstInfo is still TRUE. + // + if (FirstInfo) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_NO_INFO), gShellDebug1HiiHandle); + } + + if (Value != 0) { + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_RSVD_BITS_SET), + gShellDebug1HiiHandle, + Value + ); + } + + Print (L"\n"); +} +// +// ////////////////////////////////////////////////////////////////// +// +// Following uses QueryTable functions to simplify the coding. +// QueryTable(), PrintBitsInfo() +// +// +#define PRINT_TABLE_ITEM(Table, Key) \ + do { \ + UINTN Num; \ + CHAR16 Info[66]; \ + Num = sizeof (Table) / sizeof (TABLE_ITEM); \ + ZeroMem (Info, sizeof (Info)); \ + QueryTable (Table, Num, Key, Info, sizeof(Info)/sizeof(Info[0])); \ + Print (Info); \ + } while (0); + +#define PRINT_BITS_INFO(Table, bits) \ + do { \ + UINTN Num; \ + Num = sizeof (Table) / sizeof (TABLE_ITEM); \ + PrintBitsInfo (Table, Num, (UINT32) bits); \ + } while (0); + +/** + Display System Information (Type 1) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemWakeupType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_WAKEUP_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (SystemWakeupTypeTable, Type); +} + +/** + Display Base Board (Type 2) Feature Flags. + + @param[in] FeatureFlags The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayBaseBoardFeatureFlags ( + IN UINT8 FeatureFlags, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_BASE_BOARD_FEATURE_FLAGS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (FeatureFlags, Option); + PRINT_BITS_INFO (BaseBoardFeatureFlagsTable, FeatureFlags); +} + +/** + Display Base Board (Type 2) Board Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayBaseBoardBoardType( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_BASE_BOARD_BOARD_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (BaseBoardBoardTypeTable, Type); +} + +/** + Display System Enclosure (Type 3) Enclosure Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemEnclosureType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + // + // query table and print info + // + PRINT_TABLE_ITEM (SystemEnclosureTypeTable, Type); + + if (BIT (Type, 7) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_CHASSIS_LOCK_PRESENT), gShellDebug1HiiHandle); + } +} + +/** + Display System Enclosure (Type 3) Enclosure Status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemEnclosureStatus ( + IN UINT8 Status, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (SystemEnclosureStatusTable, Status); +} + +/** + Display System Enclosure (Type 3) Security Status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySESecurityStatus ( + IN UINT8 Status, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_SECURITY), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (SESecurityStatusTable, Status); +} + +/** + Display Processor Information (Type 4) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PROC_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (ProcessorTypeTable, Type); +} + +/** + Display Processor Information (Type 4) Upgrade. + + @param[in] Upgrade The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorUpgrade ( + IN UINT8 Upgrade, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PROC_UPDATE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Upgrade, Option); + PRINT_TABLE_ITEM (ProcessorUpgradeTable, Upgrade); +} + +/** + Display Processor Information (Type 4) Characteristics. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorCharacteristics ( + IN UINT16 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PROC_CHARACTERISTICS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_BITS_INFO (ProcessorCharacteristicsTable, Type); +} + +/** + Display Memory Controller Information (Type 5) method. + + @param[in] Method The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcErrorDetectMethod ( + IN UINT8 Method, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DETECTMETHOD), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Method, Option); + PRINT_TABLE_ITEM (McErrorDetectMethodTable, Method); +} + +/** + Display Memory Controller Information (Type 5) Capability. + + @param[in] Capability The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcErrorCorrectCapability ( + IN UINT8 Capability, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_CORRECT_CAPABILITY), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Capability, Option); + PRINT_BITS_INFO (McErrorCorrectCapabilityTable, Capability); +} + +/** + Display Memory Controller Information (Type 5) Support. + + @param[in] Support The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcInterleaveSupport ( + IN UINT8 Support, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_INTERLEAVE_SUPPORT), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Support, Option); + PRINT_TABLE_ITEM (McInterleaveSupportTable, Support); +} + +/** + Display Memory Controller Information (Type 5) speeds. + + @param[in] Speed The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcMemorySpeeds ( + IN UINT16 Speed, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_MEMORY_SPEED), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Speed, Option); + PRINT_BITS_INFO (McMemorySpeedsTable, Speed); +} + +/** + Display Memory Controller Information (Type 5) voltage. + + @param[in] Voltage The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryModuleVoltage ( + IN UINT8 Voltage, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_REQUIRED_VOLTAGES), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Voltage, Option); + PRINT_BITS_INFO (MemoryModuleVoltageTable, Voltage); +} + +/** + Display Memory Module Information (Type 6) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMmMemoryType ( + IN UINT16 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_MODULE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_BITS_INFO (MmMemoryTypeTable, Type); +} + +/** + Display Memory Module Information (Type 6) status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMmErrorStatus ( + IN UINT8 Status, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_MODULE_ERROR_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_BITS_INFO (MmErrorStatusTable, Status); +} + +/** + Display Cache Information (Type 7) SRAM Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheSRAMType ( + IN UINT16 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_CACHE_SRAM_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION ((UINT8) Type, Option); + PRINT_BITS_INFO (CacheSRAMTypeTable, (UINT8) Type); +} + +/** + Display Cache Information (Type 7) correcting Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheErrCorrectingType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_CACHE_ERROR_CORRECTING), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (CacheErrCorrectingTypeTable, Type); +} + +/** + Display Cache Information (Type 7) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheSystemCacheType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_CACHE_SYSTEM_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (CacheSystemCacheTypeTable, Type); +} + +/** + Display Cache Information (Type 7) Associativity. + + @param[in] Associativity The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheAssociativity ( + IN UINT8 Associativity, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_CACHE_ASSOCIATIVITY), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Associativity, Option); + PRINT_TABLE_ITEM (CacheAssociativityTable, Associativity); +} + +/** + Display Port Connector Information (Type 8) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPortConnectorType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PORT_CONNECTOR_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (PortConnectorTypeTable, Type); +} + +/** + Display Port Connector Information (Type 8) port type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPortType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PORT_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (PortTypeTable, Type); +} + +/** + Display System Slots (Type 9) slot type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (SystemSlotTypeTable, Type); +} + +/** + Display System Slots (Type 9) data bus width. + + @param[in] Width The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotDataBusWidth ( + IN UINT8 Width, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_DATA), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Width, Option); + PRINT_TABLE_ITEM (SystemSlotDataBusWidthTable, Width); +} + +/** + Display System Slots (Type 9) usage information. + + @param[in] Usage The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotCurrentUsage ( + IN UINT8 Usage, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_CURRENT_USAGE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Usage, Option); + PRINT_TABLE_ITEM (SystemSlotCurrentUsageTable, Usage); +} + +/** + Display System Slots (Type 9) slot length. + + @param[in] Length The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotLength ( + IN UINT8 Length, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_LENGTH), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Length, Option); + PRINT_TABLE_ITEM (SystemSlotLengthTable, Length); +} + +/** + Display System Slots (Type 9) characteristics. + + @param[in] Chara1 The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySlotCharacteristics1 ( + IN UINT8 Chara1, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SLOT_CHARACTERISTICS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Chara1, Option); + PRINT_BITS_INFO (SlotCharacteristics1Table, Chara1); +} + +/** + Display System Slots (Type 9) characteristics. + + @param[in] Chara2 The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySlotCharacteristics2 ( + IN UINT8 Chara2, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SLOT_CHARACTERISTICS_2), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Chara2, Option); + PRINT_BITS_INFO (SlotCharacteristics2Table, Chara2); +} + +/** + Display On Board Devices Information (Type 10) types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayOnboardDeviceTypes ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_ONBOARD_DEVICE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (OnboardDeviceTypesTable, Type); +} + +/** + Display System Event Log (Type 15) types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELTypes ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_EVENT_LOG_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (SELTypesTable, Type); +} + +/** + Display System Event Log (Type 15) format type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELVarDataFormatType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_EVENT_LOG_VAR_DATA_FORMAT), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (SELVarDataFormatTypeTable, Type); +} + +/** + Display System Event Log (Type 15) dw1. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPostResultsBitmapDw1 ( + IN UINT32 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_POST_RESULTS_BITMAP), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_BITS_INFO (PostResultsBitmapDw1Table, Key); +} + +/** + Display System Event Log (Type 15) dw2. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPostResultsBitmapDw2 ( + IN UINT32 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_POST_RESULTS_SECOND_DWORD), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_BITS_INFO (PostResultsBitmapDw2Table, Key); +} + +/** + Display System Event Log (Type 15) type. + + @param[in] SMType The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELSysManagementTypes ( + IN UINT32 SMType, + IN UINT8 Option + ) +{ + UINT8 Temp; + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_MANAGEMENT_TYPES), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (SMType, Option); + + // + // Deal with wide range Value + // + if (SMType >= 0x80000000) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_OEM_ASSIGNED), gShellDebug1HiiHandle); + } else if (SMType >= 0x00020000) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_RSVD_FOR_FUTURE_ASSIGN), gShellDebug1HiiHandle); + } else if (SMType >= 0x00010000) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_MANAGEMENT_PROBE), gShellDebug1HiiHandle); + } else if (SMType >= 0x31) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_RSVD_FOR_FUTURE_ASSIGN), gShellDebug1HiiHandle); + } else { + // + // Deal with One byte data + // + Temp = (UINT8) (SMType & 0x3F); + PRINT_TABLE_ITEM (SELSysManagementTypesTable, Temp); + } +} + +/** + Display Physical Memory Array (Type 16) Location. + + @param[in] Location The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMALocation ( + IN UINT8 Location, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_LOCATION), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Location, Option); + PRINT_TABLE_ITEM (PMALocationTable, Location); +} + +/** + Display Physical Memory Array (Type 16) Use. + + @param[in] Use The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMAUse ( + IN UINT8 Use, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_USE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Use, Option); + PRINT_TABLE_ITEM (PMAUseTable, Use); +} + +/** + Display Physical Memory Array (Type 16) Types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMAErrorCorrectionTypes ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_ERROR), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (PMAErrorCorrectionTypesTable, Type); +} + +/** + Display Memory Device (Type 17) form factor. + + @param[in] FormFactor The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceFormFactor ( + IN UINT8 FormFactor, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_FORM_FACTOR), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (FormFactor, Option); + PRINT_TABLE_ITEM (MemoryDeviceFormFactorTable, FormFactor); +} + +/** + Display Memory Device (Type 17) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (MemoryDeviceTypeTable, Type); +} + +/** + Display Memory Device (Type 17) details. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceTypeDetail ( + IN UINT16 Para, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_TYPE_DETAIL), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Para, Option); + PRINT_BITS_INFO (MemoryDeviceTypeDetailTable, Para); +} + +/** + Display Memory Device (Type 17) memory technology. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceMemoryTechnology ( + IN UINT8 Para, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_MEMORY_TECHNOLOGY), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Para, Option); + PRINT_TABLE_ITEM (MemoryDeviceMemoryTechnologyTable, Para); +} + +/** + Display Memory Device (Type 17) memory operating mode capability. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceMemoryOperatingModeCapability ( + IN UINT16 Para, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_MEM_OPER_MODE_CAPA), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Para, Option); + PRINT_BITS_INFO (MemoryDeviceMemoryOperatingModeCapabilityTable, Para); +} + +/** + Display 32-bit Memory Error Information (Type 18) type. + + @param[in] ErrorType The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorType ( + IN UINT8 ErrorType, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_INFO), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (ErrorType, Option); + PRINT_TABLE_ITEM (MemoryErrorTypeTable, ErrorType); +} + +/** + Display 32-bit Memory Error Information (Type 18) error granularity. + + @param[in] Granularity The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorGranularity ( + IN UINT8 Granularity, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_GRANULARITY), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Granularity, Option); + PRINT_TABLE_ITEM (MemoryErrorGranularityTable, Granularity); +} + +/** + Display 32-bit Memory Error Information (Type 18) error information. + + @param[in] Operation The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorOperation ( + IN UINT8 Operation, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_OP), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Operation, Option); + PRINT_TABLE_ITEM (MemoryErrorOperationTable, Operation); +} + +/** + Display Built-in Pointing Device (Type 21) type information. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPointingDeviceType ( + IN UINT8 Type, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_POINTING_DEVICE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (PointingDeviceTypeTable, Type); +} + +/** + Display Built-in Pointing Device (Type 21) information. + + @param[in] Interface The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPointingDeviceInterface ( + IN UINT8 Interface, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_POINTING_DEVICE_INTERFACE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Interface, Option); + PRINT_TABLE_ITEM (PointingDeviceInterfaceTable, Interface); +} + +/** + Display Portable Battery (Type 22) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPBDeviceChemistry ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PORTABLE_BATT_DEV_CHEM), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (PBDeviceChemistryTable, Key); +} + +/** + Display Voltage Probe (Type 26) location information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayVPLocation ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Loc; + + Loc = (UINT8) ((Key & 0xE0) >> 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_VOLTAGE_PROBE_LOC), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Loc, Option); + PRINT_TABLE_ITEM (VPLocationTable, Loc); +} + +/** + Display Voltage Probe (Type 26) status ype information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayVPStatus ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Status; + + Status = (UINT8) (Key & 0x1F); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_VOLTAGE_PROBE_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (VPStatusTable, Status); +} + +/** + Display Cooling (Type 27) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCoolingDeviceStatus ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Status; + + Status = (UINT8) ((Key & 0xE0) >> 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_COOLING_DEV_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (CoolingDeviceStatusTable, Status); +} + +/** + Display Cooling (Type 27) type information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCoolingDeviceType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Type; + + Type = (UINT8) (Key & 0x1F); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_COOLING_DEV_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Type, Option); + PRINT_TABLE_ITEM (CoolingDeviceTypeTable, Type); +} + +/** + Display Temperature Probe (Type 28) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayTemperatureProbeStatus ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Status; + + Status = (UINT8) ((Key & 0xE0) >> 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_TEMP_PROBE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (TemperatureProbeStatusTable, Status); +} + +/** + Display Temperature Probe (Type 28) location information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayTemperatureProbeLoc ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Loc; + + Loc = (UINT8) (Key & 0x1F); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_VOLTAGE_PROBE_LOC), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Loc, Option); + PRINT_TABLE_ITEM (TemperatureProbeLocTable, Loc); +} + +/** + Display Electrical Current Probe (Type 29) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayECPStatus ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Status; + + Status = (UINT8) ((Key & 0xE0) >> 5); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_ELEC_PROBE_STATUS), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Status, Option); + PRINT_TABLE_ITEM (ECPStatusTable, Status); +} + +/** + Display Type 29 information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayECPLoc ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + UINT8 Loc; + + Loc = (UINT8) (Key & 0x1F); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_ELEC_PROBE_LOC), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Loc, Option); + PRINT_TABLE_ITEM (ECPLocTable, Loc); +} + +/** + Display Management Device (Type 34) Type. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMDType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MANAGEMENT_DEV_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (MDTypeTable, Key); +} + +/** + Display Management Device (Type 34) Address Type. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMDAddressType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MANAGEMENT_DEV_ADDR_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (MDAddressTypeTable, Key); +} + +/** + Display Memory Channel (Type 37) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryChannelType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MEM_CHANNEL_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (MemoryChannelTypeTable, Key); +} + +/** + Display IPMI Device Information (Type 38) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayIPMIDIBMCInterfaceType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_BMC_INTERFACE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (IPMIDIBMCInterfaceTypeTable, Key); +} + +/** + Display Management Controller Host Interface (Type 42) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMCHostInterfaceType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_MC_HOST_INTERFACE_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (MCHostInterfaceTypeTable, Key); +} + +/** + Display Processor Architecture Type (Type 44). + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorArchitectureType ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + ShellPrintHiiEx (-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PROCESSOR_ARCH_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (ProcessorArchitectureTypesTable, Key); +} + +/** + Display the structure type information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayStructureTypeInfo ( + IN UINT8 Key, + IN UINT8 Option + ) +{ + // + // display + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_STRUCT_TYPE), gShellDebug1HiiHandle); + PRINT_INFO_OPTION (Key, Option); + PRINT_TABLE_ITEM (StructureTypeInfoTable, Key); +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.h new file mode 100644 index 00000000..6bc0c26f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.h @@ -0,0 +1,814 @@ +/** @file + Build a table, each item is (key, info) pair. + and give a interface of query a string out of a table. + + Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMBIOS_QUERY_TABLE_H_ +#define _SMBIOS_QUERY_TABLE_H_ + +#include <IndustryStandard/SmBios.h> + +#define QUERY_TABLE_UNFOUND 0xFF + +typedef struct TABLE_ITEM { + UINT16 Key; + CHAR16 *Info; +} TABLE_ITEM; + +// +// Print info by option +// +#define PRINT_INFO_OPTION(Value, Option) \ + do { \ + if (Option == SHOW_NONE) { \ + return ; \ + } \ + if (Option < SHOW_DETAIL) { \ + Print (L"0x%x\n", Value); \ + return ; \ + } \ + } while (0); + +/** + Given a table and a Key, return the responding info. + + Notes: + Table[Index].Key is change from UINT8 to UINT16, + in order to deal with "0xaa - 0xbb". + + For example: + DisplaySELVariableDataFormatTypes(UINT8 Type, UINT8 Option) + has a item: + "0x07-0x7F, Unused" + Now define Key = 0x7F07, that is to say: High = 0x7F, Low = 0x07. + Then all the Key Value between Low and High gets the same string + L"Unused". + + @param[in] Table The begin address of table. + @param[in] Number The number of table items. + @param[in] Key The query Key. + @param[in, out] Info Input as empty buffer; output as data buffer. + @param[in] InfoLen The max number of characters for Info. + + @return the found Key and Info is valid. + @retval QUERY_TABLE_UNFOUND and Info should be NULL. +**/ +UINT8 +QueryTable ( + IN TABLE_ITEM *Table, + IN UINTN Number, + IN UINT8 Key, + IN OUT CHAR16 *Info, + IN UINTN InfoLen + ); + +/** + Display the structure type information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayStructureTypeInfo ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display System Information (Type 1) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemWakeupType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Base Board (Type 2) Feature Flags. + + @param[in] FeatureFlags The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayBaseBoardFeatureFlags ( + IN UINT8 FeatureFlags, + IN UINT8 Option + ); + +/** + Display Base Board (Type 2) Board Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayBaseBoardBoardType( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Enclosure (Type 3) Enclosure Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemEnclosureType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Enclosure (Type 3) Enclosure Status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemEnclosureStatus ( + IN UINT8 Status, + IN UINT8 Option + ); + +/** + Display System Enclosure (Type 3) Security Status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySESecurityStatus ( + IN UINT8 Status, + IN UINT8 Option + ) +; + +/** + Display Processor Information (Type 4) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Processor Information (Type 4) Upgrade. + + @param[in] Upgrade The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorUpgrade ( + IN UINT8 Upgrade, + IN UINT8 Option + ); + +/** + Display Processor Information (Type 4) Characteristics. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayProcessorCharacteristics ( + IN UINT16 Type, + IN UINT8 Option + ); + +/** + Display Memory Controller Information (Type 5) method. + + @param[in] Method The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcErrorDetectMethod ( + IN UINT8 Method, + IN UINT8 Option + ); + +/** + Display Memory Controller Information (Type 5) Capability. + + @param[in] Capability The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcErrorCorrectCapability ( + IN UINT8 Capability, + IN UINT8 Option + ); + +/** + Display Memory Controller Information (Type 5) Support. + + @param[in] Support The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcInterleaveSupport ( + IN UINT8 Support, + IN UINT8 Option + ); + +/** + Display Memory Controller Information (Type 5) speeds. + + @param[in] Speed The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMcMemorySpeeds ( + IN UINT16 Speed, + IN UINT8 Option + ); + +/** + Display Memory Controller Information (Type 5) voltage. + + @param[in] Voltage The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryModuleVoltage ( + IN UINT8 Voltage, + IN UINT8 Option + ); + +/** + Display Memory Module Information (Type 6) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMmMemoryType ( + IN UINT16 Type, + IN UINT8 Option + ); + +/** + Display Memory Module Information (Type 6) status. + + @param[in] Status The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMmErrorStatus ( + IN UINT8 Status, + IN UINT8 Option + ); + +/** + Display Cache Information (Type 7) SRAM Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheSRAMType ( + IN UINT16 Type, + IN UINT8 Option + ); + +/** + Display Cache Information (Type 7) correcting Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheErrCorrectingType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Cache Information (Type 7) Type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheSystemCacheType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Cache Information (Type 7) Associativity. + + @param[in] Associativity The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCacheAssociativity ( + IN UINT8 Associativity, + IN UINT8 Option + ); + +/** + Display Port Connector Information (Type 8) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPortConnectorType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Port Connector Information (Type 8) port type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPortType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) slot type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) data bus width. + + @param[in] Width The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotDataBusWidth ( + IN UINT8 Width, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) usage information. + + @param[in] Usage The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotCurrentUsage ( + IN UINT8 Usage, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) slot length. + + @param[in] Length The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySystemSlotLength ( + IN UINT8 Length, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) characteristics. + + @param[in] Chara1 The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySlotCharacteristics1 ( + IN UINT8 Chara1, + IN UINT8 Option + ); + +/** + Display System Slots (Type 9) characteristics. + + @param[in] Chara2 The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySlotCharacteristics2 ( + IN UINT8 Chara2, + IN UINT8 Option + ); + +/** + Display On Board Devices Information (Type 10) types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayOnboardDeviceTypes ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Event Log (Type 15) types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELTypes ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Event Log (Type 15) format type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELVarDataFormatType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display System Event Log (Type 15) dw1. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPostResultsBitmapDw1 ( + IN UINT32 Key, + IN UINT8 Option + ); + +/** + Display System Event Log (Type 15) dw2. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPostResultsBitmapDw2 ( + IN UINT32 Key, + IN UINT8 Option + ); + +/** + Display System Event Log (Type 15) type. + + @param[in] SMType The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplaySELSysManagementTypes ( + IN UINT32 SMType, + IN UINT8 Option + ); + +/** + Display Physical Memory Array (Type 16) Location. + + @param[in] Location The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMALocation ( + IN UINT8 Location, + IN UINT8 Option + ); + +/** + Display Physical Memory Array (Type 16) Use. + + @param[in] Use The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMAUse ( + IN UINT8 Use, + IN UINT8 Option + ); + +/** + Display Physical Memory Array (Type 16) Types. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPMAErrorCorrectionTypes ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Memory Device (Type 17) form factor. + + @param[in] FormFactor The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceFormFactor ( + IN UINT8 FormFactor, + IN UINT8 Option + ); + +/** + Display Memory Device (Type 17) type. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Memory Device (Type 17) details. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceTypeDetail ( + IN UINT16 Para, + IN UINT8 Option + ); + +/** + Display Memory Device (Type 17) memory technology. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceMemoryTechnology ( + IN UINT8 Para, + IN UINT8 Option + ); + +/** + Display Memory Device (Type 17) memory operating mode capability. + + @param[in] Para The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryDeviceMemoryOperatingModeCapability ( + IN UINT16 Para, + IN UINT8 Option + ); + +/** + Display 32-bit Memory Error Information (Type 18) type. + + @param[in] ErrorType The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorType ( + IN UINT8 ErrorType, + IN UINT8 Option + ); + +/** + Display 32-bit Memory Error Information (Type 18) error granularity. + + @param[in] Granularity The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorGranularity ( + IN UINT8 Granularity, + IN UINT8 Option + ); + +/** + Display 32-bit Memory Error Information (Type 18) error information. + + @param[in] Operation The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryErrorOperation ( + IN UINT8 Operation, + IN UINT8 Option + ); + +/** + Display Built-in Pointing Device (Type 21) type information. + + @param[in] Type The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPointingDeviceType ( + IN UINT8 Type, + IN UINT8 Option + ); + +/** + Display Built-in Pointing Device (Type 21) information. + + @param[in] Interface The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPointingDeviceInterface ( + IN UINT8 Interface, + IN UINT8 Option + ); + +/** + Display Portable Battery (Type 22) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayPBDeviceChemistry ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Voltage Probe (Type 26) location information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayVPLocation ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Voltage Probe (Type 26) status ype information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayVPStatus ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Cooling (Type 27) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCoolingDeviceStatus ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Cooling (Type 27) type information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayCoolingDeviceType ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Temperature Probe (Type 28) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayTemperatureProbeStatus ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Temperature Probe (Type 28) location information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayTemperatureProbeLoc ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Electrical Current Probe (Type 29) status information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayECPStatus ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Electrical Current Probe (Type 29) location information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayECPLoc ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Management Device (Type 34) Type. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMDType ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Management Device (Type 34) Address Type. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMDAddressType ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Memory Channel (Type 37) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMemoryChannelType ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display IPMI Device Information (Type 38) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayIPMIDIBMCInterfaceType ( + IN UINT8 Key, + IN UINT8 Option + ); + +/** + Display Management Controller Host Interface (Type 42) information. + + @param[in] Key The key of the structure. + @param[in] Option The optional information. +**/ +VOID +DisplayMCHostInterfaceType ( + IN UINT8 Key, + IN UINT8 Option + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c new file mode 100644 index 00000000..bba5421f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c @@ -0,0 +1,999 @@ +/** @file + Tools of clarify the content of the smbios table. + + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include "LibSmbiosView.h" +#include "SmbiosView.h" +#include "PrintInfo.h" +#include "QueryTable.h" + +UINT8 gShowType = SHOW_DETAIL; +STATIC STRUCTURE_STATISTICS *mStatisticsTable = NULL; +STATIC STRUCTURE_STATISTICS *mSmbios64BitStatisticsTable = NULL; + +UINT8 SmbiosMajorVersion; +UINT8 SmbiosMinorVersion; + +UINTN mNumberOfSmbios64BitStructures; +UINTN mSmbios64BitTableLength; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"-t", TypeValue}, + {L"-h", TypeValue}, + {L"-s", TypeFlag}, + {L"-a", TypeFlag}, + {NULL, TypeMax} + }; + +/** + Function for 'smbiosview' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSmbiosView ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT8 StructType; + UINT16 StructHandle; + EFI_STATUS Status; + EFI_STATUS Status1; + EFI_STATUS Status2; + BOOLEAN RandomView; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_STATUS ShellStatus; + CONST CHAR16 *Temp; + + mStatisticsTable = NULL; + mSmbios64BitStatisticsTable = NULL; + Package = NULL; + ShellStatus = SHELL_SUCCESS; + + 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), gShellDebug1HiiHandle, L"smbiosview", ProblemParam); + FreePool(ProblemParam); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + ASSERT(FALSE); + } + } else { + if (ShellCommandLineGetCount(Package) > 1) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"smbiosview"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag(Package, L"-t") && ShellCommandLineGetValue(Package, L"-t") == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"smbiosview", L"-t"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if (ShellCommandLineGetFlag(Package, L"-h") && ShellCommandLineGetValue(Package, L"-h") == NULL) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"smbiosview", L"-h"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else if ( + (ShellCommandLineGetFlag(Package, L"-t") && ShellCommandLineGetFlag(Package, L"-h")) || + (ShellCommandLineGetFlag(Package, L"-t") && ShellCommandLineGetFlag(Package, L"-s")) || + (ShellCommandLineGetFlag(Package, L"-t") && ShellCommandLineGetFlag(Package, L"-a")) || + (ShellCommandLineGetFlag(Package, L"-h") && ShellCommandLineGetFlag(Package, L"-s")) || + (ShellCommandLineGetFlag(Package, L"-h") && ShellCommandLineGetFlag(Package, L"-a")) || + (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-a")) + ) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"smbiosview"); + ShellStatus = SHELL_INVALID_PARAMETER; + } else { + + // + // Init Lib + // + Status1 = LibSmbiosInit (); + Status2 = LibSmbios64BitInit (); + if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_CANNOT_GET_TABLE), gShellDebug1HiiHandle); + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + + StructType = STRUCTURE_TYPE_RANDOM; + RandomView = TRUE; + + Temp = ShellCommandLineGetValue(Package, L"-t"); + if (Temp != NULL) { + StructType = (UINT8) ShellStrToUintn (Temp); + } + + if (ShellCommandLineGetFlag(Package, L"-a")) { + gShowType = SHOW_ALL; + } + + if (!EFI_ERROR (Status1)) { + // + // Initialize the StructHandle to be the first handle + // + StructHandle = INVALID_HANDLE; + LibGetSmbiosStructure (&StructHandle, NULL, NULL); + + Temp = ShellCommandLineGetValue(Package, L"-h"); + if (Temp != NULL) { + RandomView = FALSE; + StructHandle = (UINT16) ShellStrToUintn(Temp); + } + // + // build statistics table + // + Status = InitSmbiosTableStatistics (); + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + + if (ShellCommandLineGetFlag(Package, L"-s")) { + Status = DisplayStatisticsTable (SHOW_DETAIL); + if (EFI_ERROR(Status)) { + ShellStatus = SHELL_NOT_FOUND; + } + goto Show64Bit; + } + + // + // Show SMBIOS structure information + // + Status = SMBiosView (StructType, StructHandle, gShowType, RandomView); + if (EFI_ERROR(Status)) { + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + } + +Show64Bit: + if (!EFI_ERROR (Status2)) { + // + // build statistics table + // + Status = InitSmbios64BitTableStatistics (); + if (EFI_ERROR (Status)) { + ShellStatus = SHELL_NOT_FOUND; + goto Done; + } + // + // Initialize the StructHandle to be the first handle + // + StructHandle = INVALID_HANDLE; + LibGetSmbios64BitStructure (&StructHandle, NULL, NULL); + + Temp = ShellCommandLineGetValue(Package, L"-h"); + if (Temp != NULL) { + RandomView = FALSE; + StructHandle = (UINT16) ShellStrToUintn(Temp); + } + + if (ShellCommandLineGetFlag(Package, L"-s")) { + Status = DisplaySmbios64BitStatisticsTable (SHOW_DETAIL); + if (EFI_ERROR(Status)) { + ShellStatus = SHELL_NOT_FOUND; + } + goto Done; + } + + // + // Show SMBIOS structure information + // + Status = SMBios64View (StructType, StructHandle, gShowType, RandomView); + if (EFI_ERROR(Status)) { + ShellStatus = SHELL_NOT_FOUND; + } + } + } + } +Done: + // + // Release resources + // + if (mStatisticsTable != NULL) { + // + // Release statistics table + // + FreePool (mStatisticsTable); + mStatisticsTable = NULL; + } + + if (mSmbios64BitStatisticsTable != NULL) { + // + // Release statistics table + // + FreePool (mSmbios64BitStatisticsTable); + mSmbios64BitStatisticsTable = NULL; + } + + if (Package != NULL) { + ShellCommandLineFreeVarList (Package); + } + + LibSmbiosCleanup (); + LibSmbios64BitCleanup (); + + return ShellStatus; +} + +/** + Query all structures Data from SMBIOS table and Display + the information to users as required display option. + + @param[in] QueryType Structure type to view. + @param[in] QueryHandle Structure handle to view. + @param[in] Option Display option: none,outline,normal,detail. + @param[in] RandomView Support for -h parameter. + + @retval EFI_SUCCESS print is successful. + @retval EFI_BAD_BUFFER_SIZE structure is out of the range of SMBIOS table. +**/ +EFI_STATUS +SMBiosView ( + IN UINT8 QueryType, + IN UINT16 QueryHandle, + IN UINT8 Option, + IN BOOLEAN RandomView + ) +{ + UINT16 Handle; + UINT8 *Buffer; + UINT16 Length; + UINTN Index; + + SMBIOS_STRUCTURE_POINTER SmbiosStruct; + SMBIOS_TABLE_ENTRY_POINT *SMBiosTable; + + SMBiosTable = NULL; + LibSmbiosGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_BAD_BUFFER_SIZE; + } + + if (CompareMem (SMBiosTable->AnchorString, "_SM_", 4) == 0) { + // + // Have got SMBIOS table + // + SmbiosPrintEPSInfo (SMBiosTable, Option); + + SmbiosMajorVersion = SMBiosTable->MajorVersion; + SmbiosMinorVersion = SMBiosTable->MinorVersion; + + ShellPrintEx(-1,-1,L"=========================================================\n"); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERY_STRUCT_COND), gShellDebug1HiiHandle); + + if (QueryType == STRUCTURE_TYPE_RANDOM) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE_RANDOM), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE), gShellDebug1HiiHandle, QueryType); + } + + if (RandomView) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE_RANDOM), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE), gShellDebug1HiiHandle, QueryHandle); + } + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SHOWTYPE), gShellDebug1HiiHandle); + ShellPrintEx(-1,-1,GetShowTypeString (gShowType)); + ShellPrintEx(-1,-1,L"\n\n"); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + + // + // Searching and display structure info + // + Handle = QueryHandle; + for (Index = 0; Index < SMBiosTable->NumberOfSmbiosStructures; Index++) { + // + // if reach the end of table, break.. + // + if (Handle == INVALID_HANDLE) { + break; + } + // + // handle then point to the next! + // + if (LibGetSmbiosStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) { + break; + } + + SmbiosStruct.Raw = Buffer; + + // + // if QueryType==Random, print this structure. + // if QueryType!=Random, but Hdr->Type==QueryType, also print it. + // only if QueryType != Random and Hdr->Type != QueryType, skiped it. + // + if (QueryType != STRUCTURE_TYPE_RANDOM && SmbiosStruct.Hdr->Type != QueryType) { + continue; + } + + ShellPrintEx(-1,-1,L"\n=========================================================\n"); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE_HANDLE_DUMP_STRUCT), + gShellDebug1HiiHandle, + SmbiosStruct.Hdr->Type, + SmbiosStruct.Hdr->Handle + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX_LENGTH), gShellDebug1HiiHandle, Index, Length); + // + // Addr of structure in structure in table + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ADDR), gShellDebug1HiiHandle, (UINTN) Buffer); + DumpHex (0, 0, Length, Buffer); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + + if (gShowType != SHOW_NONE) { + // + // Print structure information + // + SmbiosPrintStructure (&SmbiosStruct, gShowType); + ShellPrintEx(-1,-1,L"\n"); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + } + if (!RandomView) { + break; + } + // + // Support Execution Interrupt. + // + if (ShellGetExecutionBreakFlag ()) { + return EFI_ABORTED; + } + } + + ShellPrintEx(-1,-1,L"\n=========================================================\n"); + return EFI_SUCCESS; + } + + return EFI_BAD_BUFFER_SIZE; +} + +/** + Query all structures Data from SMBIOS table and Display + the information to users as required display option. + + @param[in] QueryType Structure type to view. + @param[in] QueryHandle Structure handle to view. + @param[in] Option Display option: none,outline,normal,detail. + @param[in] RandomView Support for -h parameter. + + @retval EFI_SUCCESS print is successful. + @retval EFI_BAD_BUFFER_SIZE structure is out of the range of SMBIOS table. +**/ +EFI_STATUS +SMBios64View ( + IN UINT8 QueryType, + IN UINT16 QueryHandle, + IN UINT8 Option, + IN BOOLEAN RandomView + ) +{ + UINT16 Handle; + UINT8 *Buffer; + UINT16 Length; + UINTN Index; + SMBIOS_STRUCTURE_POINTER SmbiosStruct; + SMBIOS_TABLE_3_0_ENTRY_POINT *SMBiosTable; + + SMBiosTable = NULL; + LibSmbios64BitGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_BAD_BUFFER_SIZE; + } + + if (CompareMem (SMBiosTable->AnchorString, "_SM3_", 5) == 0) { + // + // Have got SMBIOS table + // + Smbios64BitPrintEPSInfo (SMBiosTable, Option); + + SmbiosMajorVersion = SMBiosTable->MajorVersion; + SmbiosMinorVersion = SMBiosTable->MinorVersion; + + ShellPrintEx(-1,-1,L"=========================================================\n"); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERY_STRUCT_COND), gShellDebug1HiiHandle); + + if (QueryType == STRUCTURE_TYPE_RANDOM) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE_RANDOM), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE), gShellDebug1HiiHandle, QueryType); + } + + if (RandomView) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE_RANDOM), gShellDebug1HiiHandle); + } else { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE), gShellDebug1HiiHandle, QueryHandle); + } + + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SHOWTYPE), gShellDebug1HiiHandle); + ShellPrintEx(-1,-1,GetShowTypeString (gShowType)); + ShellPrintEx(-1,-1,L"\n\n"); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + + // + // Searching and display structure info + // + Handle = QueryHandle; + for (Index = 0; Index < mNumberOfSmbios64BitStructures; Index++) { + // + // if reach the end of table, break.. + // + if (Handle == INVALID_HANDLE) { + break; + } + // + // handle then point to the next! + // + if (LibGetSmbios64BitStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) { + break; + } + + SmbiosStruct.Raw = Buffer; + + // + // if QueryType==Random, print this structure. + // if QueryType!=Random, but Hdr->Type==QueryType, also print it. + // only if QueryType != Random and Hdr->Type != QueryType, skiped it. + // + if (QueryType != STRUCTURE_TYPE_RANDOM && SmbiosStruct.Hdr->Type != QueryType) { + continue; + } + + ShellPrintEx(-1,-1,L"\n=========================================================\n"); + ShellPrintHiiEx(-1,-1,NULL, + STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE_HANDLE_DUMP_STRUCT), + gShellDebug1HiiHandle, + SmbiosStruct.Hdr->Type, + SmbiosStruct.Hdr->Handle + ); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX_LENGTH), gShellDebug1HiiHandle, Index, Length); + // + // Addr of structure in structure in table + // + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ADDR), gShellDebug1HiiHandle, (UINTN) Buffer); + DumpHex (0, 0, Length, Buffer); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + + if (gShowType != SHOW_NONE) { + // + // Print structure information + // + SmbiosPrintStructure (&SmbiosStruct, gShowType); + ShellPrintEx(-1,-1,L"\n"); + +/* + // + // Get internal commands, such as change options. + // + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } +*/ + } + if (!RandomView) { + break; + } + // + // Support Execution Interrupt. + // + if (ShellGetExecutionBreakFlag ()) { + return EFI_ABORTED; + } + } + + ShellPrintEx(-1,-1,L"\n=========================================================\n"); + return EFI_SUCCESS; + } + + return EFI_BAD_BUFFER_SIZE; +} + +/** + Function to initialize the global mStatisticsTable object. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +InitSmbiosTableStatistics ( + VOID + ) +{ + UINT16 Handle; + UINT8 *Buffer; + UINT16 Length; + UINT16 Offset; + UINT16 Index; + + SMBIOS_STRUCTURE_POINTER SmbiosStruct; + SMBIOS_TABLE_ENTRY_POINT *SMBiosTable; + STRUCTURE_STATISTICS *StatisticsPointer; + + SMBiosTable = NULL; + LibSmbiosGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_NOT_FOUND; + } + + if (CompareMem (SMBiosTable->AnchorString, "_SM_", 4) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_TABLE), gShellDebug1HiiHandle); + return EFI_INVALID_PARAMETER; + } + // + // Allocate memory to mStatisticsTable + // + if (mStatisticsTable != NULL) { + FreePool (mStatisticsTable); + mStatisticsTable = NULL; + } + + mStatisticsTable = (STRUCTURE_STATISTICS *) AllocateZeroPool (SMBiosTable->NumberOfSmbiosStructures * sizeof (STRUCTURE_STATISTICS)); + + if (mStatisticsTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OUT_OF_MEM), gShellDebug1HiiHandle); + return EFI_OUT_OF_RESOURCES; + } + + Offset = 0; + StatisticsPointer = mStatisticsTable; + + // + // search from the first one + // + Handle = INVALID_HANDLE; + LibGetSmbiosStructure (&Handle, NULL, NULL); + for (Index = 1; Index <= SMBiosTable->NumberOfSmbiosStructures; Index++) { + // + // If reach the end of table, break.. + // + if (Handle == INVALID_HANDLE) { + break; + } + // + // After LibGetSmbiosStructure(), handle then point to the next! + // + if (LibGetSmbiosStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) { + break; + } + + SmbiosStruct.Raw = Buffer; + + // + // general statistics + // + StatisticsPointer->Index = Index; + StatisticsPointer->Type = SmbiosStruct.Hdr->Type; + StatisticsPointer->Handle = SmbiosStruct.Hdr->Handle; + StatisticsPointer->Length = Length; + StatisticsPointer->Addr = Offset; + + Offset = (UINT16) (Offset + Length); + + StatisticsPointer = &mStatisticsTable[Index]; + } + + return EFI_SUCCESS; +} + +/** + @param[in] Smbios64EntryPoint SMBIOS 64-bit entry point. + @param[out] NumberOfSmbios64Structures The number of structures in 64-bit SMBIOS table. + @param[out] Smbios64TableLength The total length of 64-bit SMBIOS table. + + @retval EFI_SUCCESS Calculation was successful. +**/ +EFI_STATUS +CalculateSmbios64BitStructureCountAndLength ( + SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios64EntryPoint, + UINTN *NumberOfSmbios64Structures, + UINTN *Smbios64TableLength +) +{ + SMBIOS_STRUCTURE_POINTER Smbios; + UINT8 *Raw; + + *Smbios64TableLength = 0; + *NumberOfSmbios64Structures = 0; + + Smbios.Raw = (UINT8 *)(UINTN)(Smbios64EntryPoint->TableAddress); + while (TRUE) { + if (Smbios.Hdr->Type == 127) { + // + // Reach the end of table type 127 + // + (*NumberOfSmbios64Structures)++; + (*Smbios64TableLength) += sizeof (SMBIOS_STRUCTURE); + return EFI_SUCCESS; + } + + Raw = Smbios.Raw; + // + // Walk to next structure + // + LibGetSmbiosString (&Smbios, (UINT16) (-1)); + // + // Length = Next structure head - this structure head + // + (*Smbios64TableLength) += ((UINTN) Smbios.Raw - (UINTN) Raw); + if ((*Smbios64TableLength) > Smbios64EntryPoint->TableMaximumSize) { + // + // The actual table length exceeds maximum table size, + // There should be something wrong with SMBIOS table. + // + return EFI_INVALID_PARAMETER; + } + (*NumberOfSmbios64Structures)++; + } +} + +/** + Function to initialize the global mSmbios64BitStatisticsTable object. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +InitSmbios64BitTableStatistics ( + VOID + ) +{ + UINT16 Handle; + UINT8 *Buffer; + UINT16 Length; + UINT16 Offset; + UINT16 Index; + EFI_STATUS Status; + SMBIOS_STRUCTURE_POINTER SmbiosStruct; + SMBIOS_TABLE_3_0_ENTRY_POINT *SMBiosTable; + STRUCTURE_STATISTICS *StatisticsPointer; + + SMBiosTable = NULL; + LibSmbios64BitGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_NOT_FOUND; + } + + if (CompareMem (SMBiosTable->AnchorString, "_SM3_", 5) != 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_TABLE), gShellDebug1HiiHandle); + return EFI_INVALID_PARAMETER; + } + // + // Allocate memory to mSmbios64BitStatisticsTable + // + if (mSmbios64BitStatisticsTable != NULL) { + FreePool (mSmbios64BitStatisticsTable); + mSmbios64BitStatisticsTable = NULL; + } + // + // Calculate number of smbios structures + // + Status = CalculateSmbios64BitStructureCountAndLength (SMBiosTable, &mNumberOfSmbios64BitStructures, &mSmbios64BitTableLength); + if ((EFI_ERROR (Status)) || (mSmbios64BitTableLength > SMBiosTable->TableMaximumSize)) { + return EFI_INVALID_PARAMETER; + } + + mSmbios64BitStatisticsTable = (STRUCTURE_STATISTICS *) AllocateZeroPool (mNumberOfSmbios64BitStructures * sizeof (STRUCTURE_STATISTICS)); + + if (mSmbios64BitStatisticsTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OUT_OF_MEM), gShellDebug1HiiHandle); + return EFI_OUT_OF_RESOURCES; + } + + Offset = 0; + StatisticsPointer = mSmbios64BitStatisticsTable; + + // + // search from the first one + // + Handle = INVALID_HANDLE; + LibGetSmbios64BitStructure (&Handle, NULL, NULL); + for (Index = 1; Index <= mNumberOfSmbios64BitStructures; Index++) { + // + // If reach the end of table, break.. + // + if (Handle == INVALID_HANDLE) { + break; + } + // + // After LibGetSmbios64BitStructure(), handle then point to the next! + // + if (LibGetSmbios64BitStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) { + break; + } + + SmbiosStruct.Raw = Buffer; + + // + // general statistics + // + StatisticsPointer->Index = Index; + StatisticsPointer->Type = SmbiosStruct.Hdr->Type; + StatisticsPointer->Handle = SmbiosStruct.Hdr->Handle; + StatisticsPointer->Length = Length; + StatisticsPointer->Addr = Offset; + + Offset = (UINT16) (Offset + Length); + + StatisticsPointer = &mSmbios64BitStatisticsTable[Index]; + } + + return EFI_SUCCESS; +} + +/** + Function to display the global mStatisticsTable object. + + @param[in] Option ECHO, NORMAL, or DETAIL control the amount of detail displayed. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +DisplayStatisticsTable ( + IN UINT8 Option + ) +{ + UINTN Index; + UINTN Num; + STRUCTURE_STATISTICS *StatisticsPointer; + SMBIOS_TABLE_ENTRY_POINT *SMBiosTable; + + SMBiosTable = NULL; + if (Option < SHOW_OUTLINE) { + return EFI_SUCCESS; + } + // + // display EPS information firstly + // + LibSmbiosGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_UNSUPPORTED; + } + + ShellPrintEx(-1,-1,L"\n============================================================\n"); + SmbiosPrintEPSInfo (SMBiosTable, Option); + + if (Option < SHOW_NORMAL) { + return EFI_SUCCESS; + } + + if (mStatisticsTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_STATS), gShellDebug1HiiHandle); + return EFI_NOT_FOUND; + } + + ShellPrintEx(-1,-1,L"============================================================\n"); + StatisticsPointer = &mStatisticsTable[0]; + Num = SMBiosTable->NumberOfSmbiosStructures; + // + // display statistics table content + // + for (Index = 1; Index <= Num; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX), gShellDebug1HiiHandle, StatisticsPointer->Index); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE), gShellDebug1HiiHandle, StatisticsPointer->Type); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE), gShellDebug1HiiHandle, StatisticsPointer->Handle); + if (Option >= SHOW_DETAIL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OFFSET), gShellDebug1HiiHandle, StatisticsPointer->Addr); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_LENGTH), gShellDebug1HiiHandle, StatisticsPointer->Length); + } + + ShellPrintEx(-1,-1,L"\n"); + StatisticsPointer = &mStatisticsTable[Index]; +/* + // + // Display 20 lines and wait for a page break + // + if (Index % 20 == 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_CONTINUE), gShellDebug1HiiHandle); + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } + } +*/ + } + + return EFI_SUCCESS; +} + +/** + Function to display the global mSmbios64BitStatisticsTable object. + + @param[in] Option ECHO, NORMAL, or DETAIL control the amount of detail displayed. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +DisplaySmbios64BitStatisticsTable ( + IN UINT8 Option + ) +{ + UINTN Index; + UINTN Num; + STRUCTURE_STATISTICS *StatisticsPointer; + SMBIOS_TABLE_3_0_ENTRY_POINT *SMBiosTable; + + SMBiosTable = NULL; + if (Option < SHOW_OUTLINE) { + return EFI_SUCCESS; + } + // + // display EPS information firstly + // + LibSmbios64BitGetEPS (&SMBiosTable); + if (SMBiosTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE), gShellDebug1HiiHandle); + return EFI_UNSUPPORTED; + } + + ShellPrintEx(-1,-1,L"\n============================================================\n"); + Smbios64BitPrintEPSInfo (SMBiosTable, Option); + + if (Option < SHOW_NORMAL) { + return EFI_SUCCESS; + } + + if (mSmbios64BitStatisticsTable == NULL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_STATS), gShellDebug1HiiHandle); + return EFI_NOT_FOUND; + } + + ShellPrintEx(-1,-1,L"============================================================\n"); + StatisticsPointer = &mSmbios64BitStatisticsTable[0]; + Num = mNumberOfSmbios64BitStructures; + // + // display statistics table content + // + for (Index = 1; Index <= Num; Index++) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_INDEX), gShellDebug1HiiHandle, StatisticsPointer->Index); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_TYPE), gShellDebug1HiiHandle, StatisticsPointer->Type); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE), gShellDebug1HiiHandle, StatisticsPointer->Handle); + if (Option >= SHOW_DETAIL) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_OFFSET), gShellDebug1HiiHandle, StatisticsPointer->Addr); + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_LENGTH), gShellDebug1HiiHandle, StatisticsPointer->Length); + } + + ShellPrintEx(-1,-1,L"\n"); + StatisticsPointer = &mSmbios64BitStatisticsTable[Index]; +/* + // + // Display 20 lines and wait for a page break + // + if (Index % 20 == 0) { + ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_CONTINUE), gShellDebug1HiiHandle); + Status = WaitEnter (); + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + return EFI_SUCCESS; + } + + return Status; + } + } +*/ + } + + return EFI_SUCCESS; +} + +/** + function to return a string of the detail level. + + @param[in] ShowType The detail level whose name is desired in clear text. + + @return A pointer to a string representing the ShowType (or 'undefined type' if not known). +**/ +CHAR16 * +GetShowTypeString ( + UINT8 ShowType + ) +{ + // + // show type + // + switch (ShowType) { + + case SHOW_NONE: + return L"SHOW_NONE"; + + case SHOW_OUTLINE: + return L"SHOW_OUTLINE"; + + case SHOW_NORMAL: + return L"SHOW_NORMAL"; + + case SHOW_DETAIL: + return L"SHOW_DETAIL"; + + case SHOW_ALL: + return L"SHOW_ALL"; + + default: + return L"Undefined type"; + } +} + diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.h new file mode 100644 index 00000000..d129edd0 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.h @@ -0,0 +1,123 @@ +/** @file + Tools of clarify the content of the smbios table. + + Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMBIOS_VIEW_H_ +#define _SMBIOS_VIEW_H_ + +#define STRUCTURE_TYPE_RANDOM (UINT8) 0xFE +#define STRUCTURE_TYPE_INVALID (UINT8) 0xFF + +typedef struct { + UINT16 Index; + UINT8 Type; + UINT16 Handle; + UINT16 Addr; // offset from table head + UINT16 Length; // total structure length +} STRUCTURE_STATISTICS; + +/** + Query all structures Data from SMBIOS table and Display + the information to users as required display option. + + @param[in] QueryType Structure type to view. + @param[in] QueryHandle Structure handle to view. + @param[in] Option Display option: none,outline,normal,detail. + @param[in] RandomView Support for -h parameter. + + @retval EFI_SUCCESS print is successful. + @retval EFI_BAD_BUFFER_SIZE structure is out of the range of SMBIOS table. +**/ +EFI_STATUS +SMBiosView ( + IN UINT8 QueryType, + IN UINT16 QueryHandle, + IN UINT8 Option, + IN BOOLEAN RandomView + ); + +/** + Query all structures Data from SMBIOS table and Display + the information to users as required display option. + + @param[in] QueryType Structure type to view. + @param[in] QueryHandle Structure handle to view. + @param[in] Option Display option: none,outline,normal,detail. + @param[in] RandomView Support for -h parameter. + + @retval EFI_SUCCESS print is successful. + @retval EFI_BAD_BUFFER_SIZE structure is out of the range of SMBIOS table. +**/ +EFI_STATUS +SMBios64View ( + IN UINT8 QueryType, + IN UINT16 QueryHandle, + IN UINT8 Option, + IN BOOLEAN RandomView + ); + +/** + Function to initialize the global mStatisticsTable object. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +InitSmbiosTableStatistics ( + VOID + ); + +/** + Function to initialize the global mSmbios64BitStatisticsTable object. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +InitSmbios64BitTableStatistics ( + VOID + ); + +/** + Function to display the global mStatisticsTable object. + + @param[in] Option ECHO, NORMAL, or DETAIL control the amount of detail displayed. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +DisplayStatisticsTable ( + IN UINT8 Option + ); + +/** + Function to display the global mSmbios64BitStatisticsTable object. + + @param[in] Option ECHO, NORMAL, or DETAIL control the amount of detail displayed. + + @retval EFI_SUCCESS print is successful. +**/ +EFI_STATUS +DisplaySmbios64BitStatisticsTable ( + IN UINT8 Option + ); + +/** + function to return a string of the detail level. + + @param[in] ShowType The detail level whose name is desired in clear text. + + @return A pointer to a string representing the ShowType (or 'undefined type' if not known). +**/ +CHAR16* +GetShowTypeString ( + UINT8 ShowType + ); + +extern UINT8 gShowType; + +extern UINTN mSmbios64BitTableLength; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni new file mode 100644 index 00000000..9433e8a2 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni @@ -0,0 +1,502 @@ +// /**
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+// (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
+// (C) Copyright 2015-2019 Hewlett Packard Enterprise Development LP<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// UefiShellDebug1CommandsLib.uni
+//
+// Abstract:
+//
+// String definitions for UEFI Shell 2.0 Debug1 profile SmBiosView command
+//
+//
+// **/
+/=#
+#langdef en-US "english"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_ACCESS_METHOD #language en-US "Access method: "
+#string STR_SMBIOSVIEW_EVENTLOGINFO_ONE_EIGHT_BIT #language en-US "Indexed I/O: 1 8-bit index port, 1 8-bit data port\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_TWO_EIGHT_BITS #language en-US "Indexed I/O: 2 8-bit index ports, 1 8-bit data port\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_ONE_SIXTEEN_BIT #language en-US "Indexed I/O: 1 16-bit index port, 1 8-bit data port\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_MEM_MAPPED_PHYS #language en-US "Memory-mapped physical 32-bit address\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_VIA_GENERAL #language en-US "Available via General-Purpose NonVolatile Data functions\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE_ASSIGN #language en-US "Available for future assignment via this specification\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR_OEM #language en-US "BIOS Vendor/OEM-specific \r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_STATUS #language en-US "Log Status: "
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_VALID #language en-US "Log area valid\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_FULL #language en-US "Log area full\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_NOT_FULL #language en-US "Log area not full\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_RES_BITS_NOT_ZERO #language en-US "Reserved bits not zero - 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_FORMAT #language en-US "Log Header Format: \r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_NO_HEADER #language en-US "No Header\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_TYPE_LOG_HEADER #language en-US "Type 1 log header\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE #language en-US "Available for future\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR #language en-US "BIOS Vendor/OEM-specific format\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_LEN #language en-US "Log Header Len: "
+#string STR_SMBIOSVIEW_EVENTLOGINFO_ONE_VAR_D #language en-US " %d\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_READ #language en-US "This record has been read\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_NOT_READ #language en-US "This record has not been read\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG #language en-US "System Event Log Header Type1 Format:\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_OEM_RESERVED #language en-US "OEM Reserved:\r\n0x%x 0x%x 0x%x 0x%x 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_TIME #language en-US "Multiple Event Time Window: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_COUNT #language en-US "Multiple Event Count Increment: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_ADDRESS #language en-US "Pre-boot Event Log Reset - CMOS Address: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_INDEX #language en-US "Pre-boot Event Log Reset - CMOS Bit Index: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUM_STARTING_OFF #language en-US "CMOS Checksum - Starting Offset: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUN_BYTE_COUNT #language en-US "CMOS Checksum - Byte Count: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_RESERVED #language en-US "Reserved: 0x%x 0x%x 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_HEADER_REVISION #language en-US "HeaderRevision: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER #language en-US "\r\nLog Header: "
+#string STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FUTURE_ASSIGN #language en-US "Available for future assignment via this specification\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_NO_STD_FORMAT #language en-US "No standard format data is available\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_SMBIOS_STRUCT_ASSOC #language en-US "SMBIOS structure associated with the hardware element that failed\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_STRUCT_HANDLE #language en-US "Structure handle = 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER #language en-US "multiple-event counter: 0x%x\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_UNUSED_AVAIL_FOR_ASSIGN #language en-US "Unused, available for assignment by this specification\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_SYSTEM #language en-US "Available for system- and OEM-specific assignments\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG_2 #language en-US "\r\nSystem Event Log records:\r\n"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_DATE #language en-US "Date/Time: "
+#string STR_SMBIOSVIEW_EVENTLOGINFO_ERROR #language en-US "error"
+#string STR_SMBIOSVIEW_EVENTLOGINFO_TIME_SIX_VARS #language en-US "%02x/%02x/%02x, %x:%x:%x\r\n"
+#string STR_SMBIOSVIEW_LIBSMBIOSVIEW_CANNOT_GET_TABLE #language en-US "Cannot get SMBIOS Table\r\n"
+#string STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR #language en-US "Get SMBIOS Table error - %r\r\n"
+#string STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC #language en-US " Get SMBIOS Structure, no buffer or length specified!\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DUMP #language en-US "Dump "
+#string STR_SMBIOSVIEW_PRINTINFO_SIZE #language en-US "\r\nsize=%d:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SMBIOSTABLE_NULL #language en-US "SMBiosTable is NULL!\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_SIGN #language en-US "%HSMBIOS Entry Point Structure:%N\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_64_BIT_ENTRY_POINT_SIGN #language en-US "%HSMBIOS 3.0 (64-bit) Entry Point Structure:%N\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BCD_REVISION #language en-US "SMBIOS BCD Revision: 0x%x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DOCREV #language en-US "SMBIOS Docrev: 0x%x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NUMBER_STRUCT #language en-US "Number of Structures: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MAX_STRUCT_SIZE #language en-US "Max Struct size: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TABLE_ADDR #language en-US "Table Address: 0x%p\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TABLE_LENGTH #language en-US "Table Length: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TABLE_MAX_SIZE #language en-US "Table Max Size: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ANCHOR_STR #language en-US "Anchor String: %a\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_EPS_CHECKSUM #language en-US "EPS Checksum: 0x%x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_LEN #language en-US "Entry Point Len: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_VERSION #language en-US "Version: %d.%d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MAJOR_VERSION #language en-US "Major version: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MINOR_VERSION #language en-US "Minor version: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENTRY_POINT_REVISION #language en-US "Entry Point revision: 0x%x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FORMATTED_AREA_NONE #language en-US "Formatted Area: None\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FORMATTED_AREA #language en-US "Formatted Area: \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTER_ACHOR #language en-US "Inter Anchor: %a\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTER_CHECKSUM #language en-US "Inter Checksum: 0x%x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FORMAT_PART_LEN #language en-US "Format part Len : %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_STRUCT_HANDLE #language en-US "Structure Handle: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOTUP_STATE #language en-US "Bootup state "
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_STATE #language en-US "Power Supply State "
+#string STR_SMBIOSVIEW_PRINTINFO_THERMAL_STATE #language en-US "Thermal state "
+#string STR_SMBIOSVIEW_PRINTINFO_SECURITY_STATUS #language en-US "Security Status "
+#string STR_SMBIOSVIEW_PRINTINFO_CONTAINED_ELEMENT #language en-US "Contained Element %d: "
+#string STR_SMBIOSVIEW_PRINTINFO_SUPOPRT #language en-US "Support "
+#string STR_SMBIOSVIEW_PRINTINFO_CURRENT #language en-US "Current "
+#string STR_SMBIOSVIEW_PRINTINFO_INSTALLED #language en-US "Installed "
+#string STR_SMBIOSVIEW_PRINTINFO_ENABLED #language en-US "Enabled "
+#string STR_SMBIOSVIEW_PRINTINFO_EXTERNAL #language en-US "External "
+#string STR_SMBIOSVIEW_PRINTINFO_SLOT_PEER_GROUPS #language en-US "Peer Groups %d:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SEGMENT_GROUP_NUM #language en-US " SegmentGroup Num: 0x%04x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BUS_NUM #language en-US " Bus Num: 0x%02x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DEV_FUNC_NUM #language en-US " DevFunc Num: 0x%02x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DATA_BUS_WIDTH #language en-US " DataBus Width: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DESC_STRING #language en-US "Description String: "
+#string STR_SMBIOSVIEW_PRINTINFO_SUPOPRTED_EVENT #language en-US "Supported Event Log Type Descriptors %d:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ACCESS_METHOD_NOT_SUPOPRTED #language en-US "Access Method %d has not supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_STRUCT_TYPE31 #language en-US "This structure is Type31, reserved by BIS (Boot Integrity Services)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MEM_DEVICE #language en-US "Memory Device %d:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DEV_LOAD #language en-US "Device Load: 0x%02x,"
+#string STR_SMBIOSVIEW_PRINTINFO_DEV_HANDLE #language en-US "Device Handle: 0x%04x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INACTIVE_STRUCT #language en-US "Inactive structure --- Needn't interpret it.\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_THIS_STRUCT_END_TABLE #language en-US "This structure indicates the End-of-table!\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_STRUCT_TYPE_UNDEFINED #language en-US "Structure Type undefined!\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR #language en-US "BIOS Characteristics: \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT #language en-US "Reserved bit\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UNKNOWN_BIT #language en-US "Unknown bit\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED #language en-US "BIOS Characteristics Not Supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ISA_SUPPORTED #language en-US "ISA is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED #language en-US "MSA is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_EISA_SUPPORTED #language en-US "EISA is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PCI_SUPPORTED #language en-US "PCI is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED #language en-US "PC Card(PCMCIA) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PLUG_PLAY_SUPPORTED #language en-US "Plug and play is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_APM_SUPPORTED #language en-US "APM is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE #language en-US "BIOS is Upgradeable(FLASH)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_SHADOWING #language en-US "BIOS shadowing is allowed\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_VESA_SUPPORTED #language en-US "VL-VESA is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ECSD_SUPPORT #language en-US "ESCD support is available\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_CD_SUPPORTED #language en-US "Boot from CD is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SELECTED_BOOT_SUPPORTED #language en-US "Selectable Boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED #language en-US "BIOS ROM is socketed\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD #language en-US "Boot From PC Card(PCMCIA)is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER #language en-US "EDD (Enhanced Disk Driver) Specification is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC #language en-US "Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5\",1k Bytes/Sector, 360 RPM) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA #language en-US "Int 13h - Japanese Floppy for Toshiba 1.2mn (3.5\", 360 RPM) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED #language en-US "Int 13h - 5.25\"/360KB Floppy Services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB #language en-US "Int 13h - 5.25\"/1.2MB Floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_720_KB #language en-US "Int 13h - 3.5\"/720KB Floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB #language en-US "Int 13h - 3.5\"/2.88MB Floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT #language en-US "Int 5h, Print screen Services is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT #language en-US "Int 9h, 8042 Keyboard services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT #language en-US "Int 14h, Serial Services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT #language en-US "Int 17h, Printer services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT #language en-US "Int 10h, CGA/Mono Video services are supported2\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NEC_PC_98 #language en-US "NEC PC-98\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_32_47 #language en-US " Bits 32:47 are reserved for BIOS Vendor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_48_64 #language en-US " Bits 48:64 are reserved for System Vendor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION #language en-US "BIOS Characteristics Extension Byte1:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED #language en-US "ACPI supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_USB_LEGACY_SUPPORTED #language en-US "USB Legacy is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AGP_SUPPORTED #language en-US "AGP is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_I2O_BOOT_SUPPORTED #language en-US "I2O boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED #language en-US "LS-120 boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE #language en-US "ATAPI ZIP Drive boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_1394_BOOT_SUPPORTED #language en-US "1394 boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED #language en-US "Smart battery supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION_2 #language en-US "BIOS Characteristics Extension Byte2:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP #language en-US "BIOS Boot Specification supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT #language en-US "Function key-initiated Network Service boot supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST #language en-US "Enable Targeted Content Distribution\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UEFI_SPEC_SUPPORT #language en-US "UEFI Specification is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE #language en-US "The SMBIOS table describes a virtual machine\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE #language en-US " Bits %d:7 are reserved for future assignment\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PROCESSOR_FAMILY #language en-US "Processor Family: "
+#string STR_SMBIOSVIEW_PRINTINFO_OTHER #language en-US "Other\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UNKNOWN #language en-US "Unknown\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL386_PROCESSOR #language en-US "Intel386(TM) Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL486_PROCESSOR #language en-US "Intel486(TM) Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PROC_FAMILY #language en-US "Pentium(R) Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PRO_PROC #language en-US "Pentium(R) Pro processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_II_PROC #language en-US "Pentium(R) II processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_PROC_MMX #language en-US "Pentium(R) processor with MMX(TM) technology\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CELERON_PROC #language en-US "Celeron(TM) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_XEON_PROC #language en-US "Pentium(R) II Xeon(TM) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_III_PROC #language en-US "Pentium(R) III Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_M1_FAMILY #language en-US "M1 Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_K5_FAMILY #language en-US "K5 Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_PC_FAMILY #language en-US "Power PC Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_PC_601 #language en-US "Power PC 601\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_PC_603 #language en-US "Power PC 603\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_PC_603_PLUS #language en-US "Power PC 603+\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_PC_604 #language en-US "Power PC 604\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ALPHA_FAMILY_2 #language en-US "Alpha Family 2\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_DUO #language en-US "Intel(R) Core(TM) Duo processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_DUO_MOBILE #language en-US "Intel(R) Core(TM) Duo mobile processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_SOLO_MOBILE #language en-US "Intel(R) Core(TM) Solo mobile processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_ATOM #language en-US "Intel(R) Atom(TM) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_QUAD_CORE #language en-US "Quad-Core AMD Opteron(TM) Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_THIRD_GENERATION #language en-US "Third-Generation AMD Opteron(TM) Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_FX_QUAD_CORE #language en-US "AMD Phenom(TM) FX Quad-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_X4_QUAD_CORE #language en-US "AMD Phenom(TM) X4 Quad-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_X2_DUAL_CORE #language en-US "AMD Phenom(TM) X2 Dual-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_ATHLON_X2_DUAL_CORE #language en-US "AMD Athlon(TM) X2 Dual-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3200_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 3200 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3000_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 3000 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5300_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 5300 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5100_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 5100 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5000_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 5000 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_LV_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor LV\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_ULV_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor ULV\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7100_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 7100 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5400_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 5400 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5200_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 5200 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7200_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 7200 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7300_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 7300 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7400_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 7400 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7400_SERIES_MULTI_CORE #language en-US "Multi-Core Intel(R) Xeon(R) processor 7400 Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_SOLO #language en-US "Intel(R) Core(TM)2 Solo processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_EXTREME #language en-US "Intel(R) Core(TM)2 Extreme processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_QUAD #language en-US "Intel(R) Core(TM)2 Quad processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_EXTREME_MOBILE #language en-US "Intel(R) Core(TM)2 Extreme mobile processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_DUO_MOBILE #language en-US "Intel(R) Core(TM)2 Duo mobile processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE2_SOLO_MOBILE #language en-US "Intel(R) Core(TM)2 Solo mobile processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CORE_I7 #language en-US "Intel(R) Core(TM) i7 processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_CELERON_DUAL_CORE #language en-US "Dual-Core Intel(R) Celeron(R) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_MULTI_CORE #language en-US "Multi-Core Intel(R) Xeon(R) processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 3xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_3_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 3xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 5xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_5_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 5xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_DUAL_CORE #language en-US "Dual-Core Intel(R) Xeon(R) processor 7xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_QUAD_CORE #language en-US "Quad-Core Intel(R) Xeon(R) processor 7xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INTEL_XEON_7_SERIES_MULTI_CORE #language en-US "Multi-Core Intel(R) Xeon(R) processor 7xxx Series\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_3000_SERIES #language en-US "AMD Opteron(TM) 3000 Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_SEMPRON_II #language en-US "AMD Sempron(TM) II Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_FX_SERIES #language en-US "AMD FX(TM) Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_Z_SERIES #language en-US "AMD Z-Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_R_SERIES #language en-US "AMD R-Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_4300_SERIES #language en-US "AMD Opteron(TM) 4300 Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_6300_SERIES #language en-US "AMD Opteron(TM) 6300 Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_3300_SERIES #language en-US "AMD Opteron(TM) 3300 Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_OPTERON_FIREPRO_SERIES #language en-US "AMD FirePro(TM) Series Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_EMBEDDED_OPTERON_QUAD_CORE #language en-US "Embedded AMD Opteron(TM) Quad-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_PHENOM_TRIPLE_CORE #language en-US "AMD Phenom(TM) Triple-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_TURION_ULTRA_DUAL_CORE_MOBILE #language en-US "AMD Turion(TM) Ultra Dual-Core Mobile Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_TURION_DUAL_CORE_MOBILE #language en-US "AMD Turion(TM) Dual-Core Mobile Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_ATHLON_DUAL_CORE #language en-US "AMD Athlon(TM) Dual-Core Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AMD_SEMPRON_SI #language en-US "AMD Sempron(TM) SI Processor Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MIPS_FAMILY #language en-US "MIPS Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SPARC_FAMILY #language en-US "SPARC Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_68040_FAMILY #language en-US "68040 Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_HOBBIT_FAMILY #language en-US "Hobbit Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_WEITEK #language en-US "Weitek\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PA_RISC_FAMILY #language en-US "PA-RISC Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_V30_FAMILY #language en-US "V30 Family\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PENTIUM_III_XEON #language en-US "Pentium(R) III Xeon(TM) Processor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RSVD_FOR_SPEC_M1 #language en-US "Reserved for specific M1 versions\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RSVD_FOR_SPEC_K5 #language en-US "Reserved for specific K5 versions\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RSVD_FOR_SPEC_PENTIUM #language en-US "Reserved for specific Pentium(R) Processor versions\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_PROC_FAMILY #language en-US "Undefined processor family and type\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PROC_INFO #language en-US "Processor Information - Voltage:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PROC_CURRENT_VOLTAGE #language en-US "Processor current voltage = (%d/10)V\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_5V_SUPOPRTED #language en-US " 5V is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_33V_SUPPORTED #language en-US " 3.3V is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_29V_SUPPORTED #language en-US " 2.9V is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT3_NOT_ZERO #language en-US "Error, reserved BIT 3 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT4_NOT_ZERO #language en-US "Error, reserved BIT 4 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT5_NOT_ZERO #language en-US "Error, reserved BIT 5 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT6_NOT_ZERO #language en-US "Error, reserved BIT 6 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT7_NOT_ZERO #language en-US "Error, reserved BIT 7 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT10_NOT_ZERO #language en-US "Error, reserved BIT 10 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT11_NOT_ZERO #language en-US "Error, reserved BIT 11 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT12_NOT_ZERO #language en-US "Error, reserved BIT 12 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT13_NOT_ZERO #language en-US "Error, reserved BIT 13 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT14_NOT_ZERO #language en-US "Error, reserved BIT 14 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIT15_NOT_ZERO #language en-US "Error, reserved BIT 15 must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PROC_STATUS #language en-US "Processor Status:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_SOCKET_POPULATED #language en-US "CPU Socket Populated\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_SOCKET_UNPOPULATED #language en-US "CPU Socket Unpopulated\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_ENABLED #language en-US "CPU Enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_DISABLED_BY_USER #language en-US "CPU Disabled by User via BIOS Setup\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_DIABLED_BY_BIOS #language en-US "CPU Disabled By BIOS (POST Error)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CPU_IDLE #language en-US "CPU is Idle, waiting to be enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_OTHERS #language en-US "Others\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RESERVED #language en-US "Reserved\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SIZE_LARGEST_MEM #language en-US "The size of the largest memory module supported (per slot): "
+#string STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_MB #language en-US "%d * %d = %d MB\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MAX_AMOUNT_MEM #language en-US "The maximum amount of memory supported by this controller: "
+#string STR_SMBIOSVIEW_PRINTINFO_HANDLES_CONTROLLED #language en-US "There are %d Handles controlled by this controller\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_HANDLES_LIST_CONTROLLED #language en-US "Handles' List controlled by this controller:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_HANDLE #language en-US "Handle%d: 0x%04x\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BANK_CONNECTIONS #language en-US "Bank Connections:"
+#string STR_SMBIOSVIEW_PRINTINFO_BANK_RAS #language en-US "Banks %d & %d(RAS# %d & %d)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BANK_RAS_2 #language en-US "Bank %d(RAS# %d)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NO_BANKS_CONNECTED #language en-US "No banks connected\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MEMORY_SIZE #language en-US "Memory Size:"
+#string STR_SMBIOSVIEW_PRINTINFO_MEM_SIZE_NOT_DETERMINABLE #language en-US " Memory Size Not determinable (Installed Size only)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MODULE_INSTALLED #language en-US " Module is installed, but no memory has been enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NOT_INSTALLED #language en-US " Not installed\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MEM_SIZE #language en-US " Memory Size: %d MB\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MEM_MODULE_DOUBLE_BANK #language en-US "The memory module has a Double-bank connection\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MEM_MODULE_SINGLE_BANK #language en-US "The memory module has a Single-bank connection\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SLOT_ID #language en-US " Slot Id:"
+#string STR_SMBIOSVIEW_PRINTINFO_LOGICAL_MICRO_CHAN #language en-US " the logical Micro Channel slot number is:"
+#string STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D #language en-US " %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15 #language en-US " error, not 1-15.\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_LOGICAL_EISA_NUM #language en-US " the logical EISA slot number is:"
+#string STR_SMBIOSVIEW_PRINTINFO_IDENTIFIES_ADAPTER_NUM #language en-US " Identifies the Adapter Number is: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT #language en-US " the value present in the Slot Number field of the PCI Interrupt Routing table entry that is associated with this slot is: %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_SLOT_ID #language en-US " undefined Slot Id\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_CONFIGURATION #language en-US "Cache Configuration:\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_WRITE_THROUGH #language en-US "Write Through\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_WRITE_BACK #language en-US "Write Back\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_VARIES_WITH_MEM_ADDR #language en-US "Varies with Memory Address\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_INTERNAL #language en-US "Internal\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_EXTERNAL #language en-US "External\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_SOCKETED #language en-US "Socketed\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_NOT_SOCKETED #language en-US "Not Socketed\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CACHE_LEVEL #language en-US "Level %d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SYSTEM_BOOT_STATUS #language en-US "System Boot Status: "
+#string STR_SMBIOSVIEW_PRINTINFO_NO_ERRORS_DETECTED #language en-US " No errors detected"
+#string STR_SMBIOSVIEW_PRINTINFO_NO_BOOTABLE_MEDIA #language en-US " No bootable media"
+#string STR_SMBIOSVIEW_PRINTINFO_NORMAL_OP_SYSTEM #language en-US " The \"normal\" unable to load operating system."
+#string STR_SMBIOSVIEW_PRINTINFO_FIRMWARE_DETECTED #language en-US " Firmware-detected hardware problem, including \"unknown\" failure types."
+#string STR_SMBIOSVIEW_PRINTINFO_OP_SYSTEM #language en-US " Operating system-detected hardware failure."
+#string STR_SMBIOSVIEW_PRINTINFO_USER_REQUESTED_BOOT #language en-US " User-requested boot, usually via a keystroke"
+#string STR_SMBIOSVIEW_PRINTINFO_SYSTEM_SECURITY_VIOLATION #language en-US " System security violation"
+#string STR_SMBIOSVIEW_PRINTINFO_PREV_REQ_IMAGE #language en-US " Previously-requested image. "
+#string STR_SMBIOSVIEW_PRINTINFO_WATCHDOG_TIMER #language en-US " A system watchdog timer expired, causing the system to reboot."
+#string STR_SMBIOSVIEW_PRINTINFO_RSVD_FUTURE_ASSIGNMENT #language en-US " Reserved for future assignment via this specification. "
+#string STR_SMBIOSVIEW_PRINTINFO_VENDOR_OEM_SPECIFIC #language en-US " Vendor/OEM-specific implementations. The Vendor/OEM identifier is the \"Manufacturer\" string found in the System Identification structure."
+#string STR_SMBIOSVIEW_PRINTINFO_PRODUCT_SPEC_IMPLMENTATION #language en-US "Product-specific implementations. The product identifier is formed by the concatenation of the \"Manufacturer\" and \"Product Name\" strings found in the System Information structure."
+#string STR_SMBIOSVIEW_PRINTINFO_ERROR_VALUE #language en-US "Error value\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SBDS_MANUFACTURE_DATE #language en-US "SBDS Manufacture Date: "
+#string STR_SMBIOSVIEW_PRINTINFO_MONTH_DAY_YEAR #language en-US "%02d/%02d/%4d\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SYSTEM_RESET_CAPABILITIES #language en-US "System Reset Capabilities: "
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_RESERVED_ZERO #language en-US "Bits 7:6 are reserved bits, must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_WATCHDOG_TIMER_2 #language en-US "System contains a watchdog timer\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SYSTEM_NOT_CONTAIN_TIMER #language en-US "System does not contain a watchdog timer\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOT_OPTION_LIMIT #language en-US "Boot Option on Limit: "
+#string STR_SMBIOSVIEW_PRINTINFO_OP_SYSTEM_2 #language en-US "Operating system\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SYSTEM_UTIL #language en-US "System utilities\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_DO_NOT_REBOOT #language en-US "Do not reboot\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOT_OPTION #language en-US "Boot Option :"
+#string STR_SMBIOSVIEW_PRINTINFO_DO_NOT_REBOOT #language en-US "Do not reboot\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_HARDWARE_SECURITY_SET #language en-US "Hardware Security Settings: \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_ON_PASSWORD #language en-US "Power-on Password Status: "
+#string STR_SMBIOSVIEW_PRINTINFO_DISABLED #language en-US "Disabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENABLED_NEWLINE #language en-US "Enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NOT_IMPLEMENTED #language en-US "Not Implemented\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_PASSWORD #language en-US "Keyboard Password Status: "
+#string STR_SMBIOSVIEW_PRINTINFO_ADMIN_PASSWORD_STATUS #language en-US "Administrator Password Status: "
+#string STR_SMBIOSVIEW_PRINTINFO_FRONT_PANEL_RESET #language en-US "Front Panel Reset Status: "
+#string STR_SMBIOSVIEW_PRINTINFO_CONNECTIONS #language en-US "Connections: "
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_RESERVED_ZERO_2 #language en-US "Bits 7:2 are reserved bits, must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_OUTBOUND_CONN_ENABLED #language en-US "Outbound Connection Enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_OTUBOUND_CONN_DISABLED #language en-US "Outbound Connection Disabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INBOIUND_CONN_ENABLED #language en-US "Inbound Connection Enabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INBOUND_CONN_DISABLED #language en-US "Inbound Connection Disabled\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_CHAR #language en-US "Power Supply Characteristics: \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_15_14_RSVD #language en-US "Bits 15:14 are reserved bits, must be zero\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TYPE #language en-US "Type - "
+#string STR_SMBIOSVIEW_PRINTINFO_OTHER_SPACE #language en-US " Other\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_LINEAR #language en-US " Linear\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SWITCHING #language en-US " Switching\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BATTERY #language en-US " Battery\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UPS #language en-US " UPS\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CONVERTER #language en-US " Converter\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_REGULATOR #language en-US " Regulator\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RESERVED_2 #language en-US " Reserved \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_STATUS_DASH #language en-US " Status - "
+#string STR_SMBIOSVIEW_PRINTINFO_OK #language en-US " OK\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NON_CRITICAL #language en-US " Non-critical\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_CRITICAL_POWER_SUPPLY #language en-US " Critical, power supply has failed and has been taken off-line\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_UNDEFINED #language en-US " Undefined \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_INPUT_VOLTAGE_RANGE #language en-US "Input Voltage Range Switching - "
+#string STR_SMBIOSVIEW_PRINTINFO_MANUAL #language en-US " Manual\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_AUTO_SWITCH #language en-US " Auto-switch\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_WIDE_RANGE #language en-US " Wide range\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_NOT_APPLICABLE #language en-US " Not applicable\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_RESERVED_3 #language en-US " Reserved \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_UNPLUGGED #language en-US "Power supply is unplugged from the wall\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_PLUGGED #language en-US "Power supply is plugged into the wall\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_PRESENT #language en-US "Power supply is present\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_NOT_PRESENT #language en-US "Power supply is not present\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_REPLACE #language en-US "Power supply is hot replaceable\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_POWER_SUPPLY_NOT_REPLACE #language en-US "Power supply is not hot replaceable\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_SIZE #language en-US "BiosSize: %d KB\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_EXTENDED_BIOS_SIZE #language en-US "ExtendedBiosSize: %d %s\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_NO_INFO #language en-US "No Info"
+#string STR_SMBIOSVIEW_QUERYTABLE_RSVD_BITS_SET #language en-US "\r\nIt also has reserved bits set 1 --- reserved bits: 0x%x"
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_WAKEUP_TYPE #language en-US "System Wakeup Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_BASE_BOARD_FEATURE_FLAGS #language en-US "Base Board Feature Flags:"
+#string STR_SMBIOSVIEW_QUERYTABLE_BASE_BOARD_BOARD_TYPE #language en-US "Base Board Board Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_TYPE #language en-US "System Enclosure or Chassis Types:"
+#string STR_SMBIOSVIEW_QUERYTABLE_CHASSIS_LOCK_PRESENT #language en-US "Chassis Lock present\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_STATUS #language en-US "System Enclosure or Chassis Status: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_CHASSIS_SECURITY #language en-US "System Enclosure or Chassis Security Status: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PROC_TYPE #language en-US "Processor Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PROC_UPDATE #language en-US "Processor Upgrade: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PROC_CHARACTERISTICS #language en-US "Processor Characteristics: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DETECTMETHOD #language en-US "Memory Controller Error DetectMethod:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_CORRECT_CAPABILITY #language en-US "Memory Controller Error Correct Capability:\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_INTERLEAVE_SUPPORT #language en-US "Memory Controller Interleave Support:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_MEMORY_SPEED #language en-US "Memory Controller Memory Speed:"
+#string STR_SMBIOSVIEW_QUERYTABLE_REQUIRED_VOLTAGES #language en-US "The required voltages for each memory module sockets:\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_MODULE_TYPE #language en-US "Memory Module Memory Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_MODULE_ERROR_STATUS #language en-US "Memory Module Error Status: "
+#string STR_SMBIOSVIEW_QUERYTABLE_CACHE_SRAM_TYPE #language en-US "Cache SRAM Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_CACHE_ERROR_CORRECTING #language en-US "Cache Error Correcting Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_CACHE_SYSTEM_TYPE #language en-US "Cache System Cache Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_CACHE_ASSOCIATIVITY #language en-US "Cache Associativity:"
+#string STR_SMBIOSVIEW_QUERYTABLE_PORT_CONNECTOR_TYPE #language en-US "Port Connector Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PORT_TYPE #language en-US "Port Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_TYPE #language en-US "System Slot Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_DATA #language en-US "System Slot Data Bus Width: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_CURRENT_USAGE #language en-US "System Slot Current Usage: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_SLOT_LENGTH #language en-US "System Slot Length: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SLOT_CHARACTERISTICS #language en-US "Slot characteristics 1: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SLOT_CHARACTERISTICS_2 #language en-US "Slot characteristics 2: "
+#string STR_SMBIOSVIEW_QUERYTABLE_ONBOARD_DEVICE_TYPE #language en-US "Onboard Device Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_EVENT_LOG_TYPE #language en-US "System Event Log Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_EVENT_LOG_VAR_DATA_FORMAT #language en-US "Event Log Variable Data Format Types: "
+#string STR_SMBIOSVIEW_QUERYTABLE_POST_RESULTS_BITMAP #language en-US "POST Results Bitmap - First DWORD:\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_POST_RESULTS_SECOND_DWORD #language en-US "POST Results Bitmap - Second DWORD:\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_MANAGEMENT_TYPES #language en-US "System Management Types: "
+#string STR_SMBIOSVIEW_QUERYTABLE_OEM_ASSIGNED #language en-US "OEM assigned\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_RSVD_FOR_FUTURE_ASSIGN #language en-US "Reserved for future assignment via this specification\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_SYSTEM_MANAGEMENT_PROBE #language en-US "A system-management probe or cooling device is out-of-range\r\n"
+#string STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_LOCATION #language en-US "Physical Memory Array Location: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_USE #language en-US "Physical Memory Array Use: "
+#string STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_ERROR #language en-US "Physical Memory Array Error Correction Types: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_FORM_FACTOR #language en-US "Memory Device - Form Factor: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_TYPE #language en-US "Memory Device - Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_TYPE_DETAIL #language en-US "Memory Device - Type Detail: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_MEMORY_TECHNOLOGY #language en-US "Memory Device - Memory Technology: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_DEVICE_MEM_OPER_MODE_CAPA #language en-US "Memory Device - Memory Operating Mode Capability: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_INFO #language en-US "32-bit Memory Error Information - Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_GRANULARITY #language en-US "Memory Error - Error granularity: "
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_ERROR_OP #language en-US "Memory Error - Error Operation: "
+#string STR_SMBIOSVIEW_QUERYTABLE_POINTING_DEVICE_TYPE #language en-US "Pointing Device - Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_POINTING_DEVICE_INTERFACE #language en-US "Pointing Device - Interface:"
+#string STR_SMBIOSVIEW_QUERYTABLE_PORTABLE_BATT_DEV_CHEM #language en-US "Portable Battery - Device Chemistry:"
+#string STR_SMBIOSVIEW_QUERYTABLE_VOLTAGE_PROBE_LOC #language en-US "Voltage Probe - Location:"
+#string STR_SMBIOSVIEW_QUERYTABLE_VOLTAGE_PROBE_STATUS #language en-US "Voltage Probe - Status:"
+#string STR_SMBIOSVIEW_QUERYTABLE_COOLING_DEV_STATUS #language en-US "Cooling Device - Status: "
+#string STR_SMBIOSVIEW_QUERYTABLE_COOLING_DEV_TYPE #language en-US "Cooling Device - Type: "
+#string STR_SMBIOSVIEW_QUERYTABLE_TEMP_PROBE #language en-US "Temperature Probe - Status:"
+#string STR_SMBIOSVIEW_QUERYTABLE_ELEC_PROBE_STATUS #language en-US "Electrical Current Probe - Status:"
+#string STR_SMBIOSVIEW_QUERYTABLE_ELEC_PROBE_LOC #language en-US "Electrical Current Probe - Location:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MANAGEMENT_DEV_TYPE #language en-US "Management Device Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MANAGEMENT_DEV_ADDR_TYPE #language en-US "Management Device - Address Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MEM_CHANNEL_TYPE #language en-US "Memory Channel Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_BMC_INTERFACE_TYPE #language en-US "BMC Interface Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_MC_HOST_INTERFACE_TYPE #language en-US "MC Host Interface Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_STRUCT_TYPE #language en-US "Structure Type:"
+#string STR_SMBIOSVIEW_QUERYTABLE_PROCESSOR_ARCH_TYPE #language en-US "Processor Architecture Type:"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_ONE_VAR_ARGV #language en-US "%s "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUERY_STRUCT_COND #language en-US "Query Structure, conditions are:\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE_RANDOM #language en-US "QueryType = Random \r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUERYTYPE #language en-US "QueryType = %d\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE_RANDOM #language en-US "QueryHandle = Random\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUERYHANDLE #language en-US "QueryHandle = 0x%x\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOWTYPE #language en-US "ShowType = "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_TYPE_HANDLE_DUMP_STRUCT #language en-US "Type=%d, Handle=0x%x\r\nDump Structure as:\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_INDEX_LENGTH #language en-US "Index=%d,Length=0x%x,"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_ADDR #language en-US "Addr=0x%p\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_ENTRYLEN #language en-US "Entry Length: 0x%x\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_REFERENCEDHANDLE #language en-US "Referenced Handle: 0x%x\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_REFERENCEDOFFSET #language en-US "Referenced Offset: 0x%x\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_Q #language en-US "\r\n%HEnter%N to continue, %H:q%N to exit, %H:[0-3]%N to change mode, %H/?%N for help\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_UTILITY #language en-US " SMBIOS Utility ---- smbiosview HELP Information\r\n\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_USAGE #language en-US "Usage:\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_HSMBIOSVIEW #language en-US "%Hsmbiosview [-t type] | [-h handle] | [-s] | [-a]%N\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_EXAMPLES #language en-US "Examples:\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOW_STAT_INFO #language en-US "%H>smbiosview -s %N - Show statistics information\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOW_ALL_STRUCT_TYPE #language en-US "%H>smbiosview -t 8 %N - Show all structures of type=8\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOW_STRUCT_HANDLE #language en-US "%H>smbiosview -h 25 %N - Show structure of handle=0x25\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOW_ALL_OUTPUT_TO_FILE #language en-US "%H>smbiosview -a > 1.log%N - Show all and output to file 1.log\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_INTERNAL_COMMANDS #language en-US "Internal commands:\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_QUIT_SMBIOSVIEW #language en-US "%H:q%N -------- quit smbiosview\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CHANGE_DISPLAY_NONE #language en-US "%H:0%N -------- Change smbiosview display NONE info\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CHANGE_DISPLAY_OUTLINE #language en-US "%H:1%N -------- Change smbiosview display OUTLINE info\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CHANGE_DISPLAY_NORMAL #language en-US "%H:2%N -------- Change smbiosview display NORMAL info\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CHANGE_DISPLAY_DETAIL #language en-US "%H:3%N -------- Change smbiosview display DETAIL info\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SHOW_HELP #language en-US "%H/?%N -------- Show help\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_INDEX #language en-US "Index=%04d "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_TYPE #language en-US "Type=%03d "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE #language en-US "Handle=0x%04x "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_OFFSET #language en-US "Offset=0x%04x "
+#string STR_SMBIOSVIEW_SMBIOSVIEW_LENGTH #language en-US "Length=0x%04x"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_ENTER_CONTINUE #language en-US "Press Enter to continue..\r\n"
+#string STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUF_SPEC_WHEN_STRUCT #language en-US "smbiosview: No buffer specified when get structure\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_NOT_SPEC #language en-US "SmbiosView: Type # not specified\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_HANDLE_NOT_SPEC #language en-US "SmbiosView: Handle # not specified\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_UNKNOWN_FLAG #language en-US "\r\nSmbiosView: Unknown flag\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_TABLE #language en-US "SmbiosView: Cannot access SMBIOS table\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_UNKNOWN_INTERNAL_COMMAND #language en-US "\r\nSmbiosView: Unknown internal command\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_SMBIOS_TABLE #language en-US "SmbiosView: SMBIOS table damaged\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_OUT_OF_MEM #language en-US "SmbiosView: Out of memory\r\n"
+#string STR_SMBIOSVIEW_SMBIOSVIEW_CANNOT_ACCESS_STATS #language en-US "SmbiosView: Cannot access statistics table\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CHAR #language en-US "TPM Device Characteristics: \r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CHAR_NOT_SUPPORTED #language en-US "TPM Device Characteristics Not Supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_FWU #language en-US "Family configurable via firmware update\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_PLAT_SW #language en-US "Family configurable via platform software support\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TPM_DEVICE_CONFIG_OEM #language en-US "Family configurable via OEM proprietary mechanism\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_06_63 #language en-US "Bits 6:63 are reserved\r\n"
+
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c new file mode 100644 index 00000000..6530bc7c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c @@ -0,0 +1,421 @@ +/** @file + Main file for NULL named library for debug1 profile shell command functions. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UefiShellDebug1CommandsLib.h" +#include <Library/BcfgCommandLib.h> + +STATIC CONST CHAR16 mFileName[] = L"Debug1Commands"; +EFI_HII_HANDLE gShellDebug1HiiHandle = NULL; + +/** + Gets the debug file name. This will be used if HII is not working. + + @retval NULL No file is available. + @return The NULL-terminated filename to get help from. +**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameDebug1 ( + VOID + ) +{ + return (mFileName); +} + +/** + Constructor for the Shell Debug1 Commands library. + + @param ImageHandle the image handle of the process + @param SystemTable the EFI System Table pointer + + @retval EFI_SUCCESS the shell command handlers were installed sucessfully + @retval EFI_UNSUPPORTED the shell level required was not found. +**/ +EFI_STATUS +EFIAPI +UefiShellDebug1CommandsLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // check our bit of the profiles mask + // + if ((PcdGet8(PcdShellProfileMask) & BIT1) == 0) { + return (EFI_SUCCESS); + } + + // + // install the HII stuff. + // + gShellDebug1HiiHandle = HiiAddPackages (&gShellDebug1HiiGuid, gImageHandle, UefiShellDebug1CommandsLibStrings, NULL); + if (gShellDebug1HiiHandle == NULL) { + return (EFI_DEVICE_ERROR); + } + + // + // install our shell command handlers that are always installed + // + ShellCommandRegisterCommandName(L"setsize", ShellCommandRunSetSize , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETSIZE) ); + ShellCommandRegisterCommandName(L"comp", ShellCommandRunComp , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_COMP) ); + ShellCommandRegisterCommandName(L"mode", ShellCommandRunMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MODE) ); + ShellCommandRegisterCommandName(L"memmap", ShellCommandRunMemMap , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MEMMAP) ); + ShellCommandRegisterCommandName(L"eficompress", ShellCommandRunEfiCompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFICOMPRESS) ); + ShellCommandRegisterCommandName(L"efidecompress", ShellCommandRunEfiDecompress , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EFIDCOMPRESS) ); + ShellCommandRegisterCommandName(L"dmem", ShellCommandRunDmem , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMEM) ); + ShellCommandRegisterCommandName(L"loadpcirom", ShellCommandRunLoadPciRom , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD_PCI_ROM) ); + ShellCommandRegisterCommandName(L"mm", ShellCommandRunMm , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_MM) ); + ShellCommandRegisterCommandName(L"setvar", ShellCommandRunSetVar , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SETVAR) ); + ShellCommandRegisterCommandName(L"sermode", ShellCommandRunSerMode , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SERMODE) ); + ShellCommandRegisterCommandName(L"pci", ShellCommandRunPci , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_PCI) ); + ShellCommandRegisterCommandName(L"smbiosview", ShellCommandRunSmbiosView , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_SMBIOSVIEW) ); + ShellCommandRegisterCommandName(L"dmpstore", ShellCommandRunDmpStore , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DMPSTORE) ); + ShellCommandRegisterCommandName(L"dblk", ShellCommandRunDblk , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_DBLK) ); + ShellCommandRegisterCommandName(L"edit", ShellCommandRunEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_EDIT) ); + ShellCommandRegisterCommandName(L"hexedit", ShellCommandRunHexEdit , ShellCommandGetManFileNameDebug1, 0, L"Debug1", TRUE, gShellDebug1HiiHandle, STRING_TOKEN(STR_GET_HELP_HEXEDIT) ); + + ShellCommandRegisterAlias(L"dmem", L"mem"); + + BcfgLibraryRegisterBcfgCommand(ImageHandle, SystemTable, L"Debug1"); + + return (EFI_SUCCESS); +} + +/** + Destructor for the library. free any resources. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. +**/ +EFI_STATUS +EFIAPI +UefiShellDebug1CommandsLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (gShellDebug1HiiHandle != NULL) { + HiiRemovePackages(gShellDebug1HiiHandle); + } + + BcfgLibraryUnregisterBcfgCommand(ImageHandle, SystemTable); + return (EFI_SUCCESS); +} + + +/** + Function returns a system configuration table that is stored in the + EFI System Table based on the provided GUID. + + @param[in] TableGuid A pointer to the table's GUID type. + @param[in, out] Table On exit, a pointer to a system configuration table. + + @retval EFI_SUCCESS A configuration table matching TableGuid was found. + @retval EFI_NOT_FOUND A configuration table matching TableGuid was not found. +**/ +EFI_STATUS +GetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + IN OUT VOID **Table + ) +{ + UINTN Index; + ASSERT (Table != NULL); + + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (CompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { + *Table = gST->ConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + Clear the line at the specified Row. + + @param[in] Row The row number to be cleared ( start from 1 ) + @param[in] LastCol The last printable column. + @param[in] LastRow The last printable row. +**/ +VOID +EditorClearLine ( + IN UINTN Row, + IN UINTN LastCol, + IN UINTN LastRow + ) +{ + UINTN Col; + CHAR16 Line[200]; + + if (Row == 0) { + Row = 1; + } + + // + // prepare a blank line + // If max column is larger, split to multiple prints. + // + SetMem16 (Line, sizeof (Line), L' '); + Line[ARRAY_SIZE (Line) - 1] = CHAR_NULL; + + for (Col = 1; Col <= LastCol; Col += ARRAY_SIZE (Line) - 1) { + if (Col + ARRAY_SIZE (Line) - 1 > LastCol) { + if (Row == LastRow) { + // + // if CHAR_NULL is still at position LastCol, it will cause first line error + // + Line[(LastCol - 1) % (ARRAY_SIZE (Line) - 1)] = CHAR_NULL; + } else { + Line[LastCol % (ARRAY_SIZE (Line) - 1)] = CHAR_NULL; + } + } + + // + // print out the blank line + // + ShellPrintEx ((INT32) Col - 1, (INT32) Row - 1, Line); + } +} + +/** + Determine if the character is valid for a filename. + + @param[in] Ch The character to test. + + @retval TRUE The character is valid. + @retval FALSE The character is not valid. +**/ +BOOLEAN +IsValidFileNameChar ( + IN CONST CHAR16 Ch + ) +{ + // + // See if there are any illegal characters within the name + // + if (Ch < 0x20 || Ch == L'\"' || Ch == L'*' || Ch == L'/' || Ch == L'<' || Ch == L'>' || Ch == L'?' || Ch == L'|') { + return FALSE; + } + + return TRUE; +} + +/** + Check if file name has illegal characters. + + @param Name The filename to check. + + @retval TRUE The filename is ok. + @retval FALSE The filename is not ok. +**/ +BOOLEAN +IsValidFileName ( + IN CONST CHAR16 *Name + ) +{ + + UINTN Index; + UINTN Len; + + // + // check the length of Name + // + for (Len = 0, Index = StrLen (Name) - 1; Index + 1 != 0; Index--, Len++) { + if (Name[Index] == '\\' || Name[Index] == ':') { + break; + } + } + + if (Len == 0 || Len > 255) { + return FALSE; + } + // + // check whether any char in Name not appears in valid file name char + // + for (Index = 0; Index < StrLen (Name); Index++) { + if (!IsValidFileNameChar (Name[Index])) { + return FALSE; + } + } + + return TRUE; +} + +/** + Find a filename that is valid (not taken) with the given extension. + + @param[in] Extension The file extension. + + @retval NULL Something went wrong. + @return the valid filename. +**/ +CHAR16 * +EditGetDefaultFileName ( + IN CONST CHAR16 *Extension + ) +{ + EFI_STATUS Status; + UINTN Suffix; + CHAR16 *FileNameTmp; + + Suffix = 0; + + do { + FileNameTmp = CatSPrint (NULL, L"NewFile%d.%s", Suffix, Extension); + + // + // after that filename changed to path + // + Status = ShellFileExists (FileNameTmp); + + if (Status == EFI_NOT_FOUND) { + return FileNameTmp; + } + + FreePool (FileNameTmp); + FileNameTmp = NULL; + Suffix++; + } while (Suffix != 0); + + FreePool (FileNameTmp); + return NULL; +} + +/** + Read a file into an allocated buffer. The buffer is the responsibility + of the caller to free. + + @param[in] FileName The filename of the file to open. + @param[out] Buffer Upon successful return, the pointer to the + address of the allocated buffer. + @param[out] BufferSize If not NULL, then the pointer to the size + of the allocated buffer. + @param[out] ReadOnly Upon successful return TRUE if the file is + read only. FALSE otherwise. + + @retval EFI_NOT_FOUND The filename did not represent a file in the + file system. + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR The file read operation failed. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_INVALID_PARAMETER FileName was NULL. + @retval EFI_INVALID_PARAMETER FileName was a directory. +**/ +EFI_STATUS +ReadFileIntoBuffer ( + IN CONST CHAR16 *FileName, + OUT VOID **Buffer, + OUT UINTN *BufferSize OPTIONAL, + OUT BOOLEAN *ReadOnly + ) +{ + VOID *InternalBuffer; + UINTN FileSize; + SHELL_FILE_HANDLE FileHandle; + BOOLEAN CreateFile; + EFI_STATUS Status; + EFI_FILE_INFO *Info; + + InternalBuffer = NULL; + FileSize = 0; + FileHandle = NULL; + CreateFile = FALSE; + Status = EFI_SUCCESS; + Info = NULL; + + if (FileName == NULL || Buffer == NULL || ReadOnly == NULL) { + return (EFI_INVALID_PARAMETER); + } + + // + // try to open the file + // + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0); + + if (!EFI_ERROR(Status)) { + ASSERT(CreateFile == FALSE); + if (FileHandle == NULL) { + return EFI_LOAD_ERROR; + } + + Info = ShellGetFileInfo(FileHandle); + + if (Info->Attribute & EFI_FILE_DIRECTORY) { + FreePool (Info); + return EFI_INVALID_PARAMETER; + } + + if (Info->Attribute & EFI_FILE_READ_ONLY) { + *ReadOnly = TRUE; + } else { + *ReadOnly = FALSE; + } + // + // get file size + // + FileSize = (UINTN) Info->FileSize; + + FreePool (Info); + } else if (Status == EFI_NOT_FOUND) { + // + // file not exists. add create and try again + // + Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); + if (EFI_ERROR (Status)) { + return Status; + } else { + // + // it worked. now delete it and move on with the name (now validated) + // + Status = ShellDeleteFile (&FileHandle); + if (Status == EFI_WARN_DELETE_FAILURE) { + Status = EFI_ACCESS_DENIED; + } + if (EFI_ERROR (Status)) { + return Status; + } + } + // + // file doesn't exist, so set CreateFile to TRUE and can't be read-only + // + CreateFile = TRUE; + *ReadOnly = FALSE; + } + + // + // the file exists + // + if (!CreateFile) { + // + // allocate buffer to read file + // + InternalBuffer = AllocateZeroPool (FileSize); + if (InternalBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // read file into InternalBuffer + // + Status = ShellReadFile (FileHandle, &FileSize, InternalBuffer); + ShellCloseFile(&FileHandle); + FileHandle = NULL; + if (EFI_ERROR (Status)) { + SHELL_FREE_NON_NULL (InternalBuffer); + return EFI_LOAD_ERROR; + } + } + *Buffer = InternalBuffer; + if (BufferSize != NULL) { + *BufferSize = FileSize; + } + return (EFI_SUCCESS); + +} diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h new file mode 100644 index 00000000..3f1ecee4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h @@ -0,0 +1,377 @@ +/** @file + Main file for NULL named library for Profile1 shell command functions. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _UEFI_SHELL_DEBUG1_COMMANDS_LIB_H_ +#define _UEFI_SHELL_DEBUG1_COMMANDS_LIB_H_ + +#include <Uefi.h> + +#include <Guid/GlobalVariable.h> +#include <Guid/ConsoleInDevice.h> +#include <Guid/ConsoleOutDevice.h> +#include <Guid/FileSystemInfo.h> +#include <Guid/ShellLibHiiGuid.h> + +#include <Protocol/Shell.h> +#include <Protocol/ShellParameters.h> +#include <Protocol/DevicePath.h> +#include <Protocol/LoadedImage.h> +#include <Protocol/UnicodeCollation.h> +#include <Protocol/DriverDiagnostics2.h> +#include <Protocol/DriverDiagnostics.h> +#include <Protocol/PlatformDriverOverride.h> +#include <Protocol/BusSpecificDriverOverride.h> +#include <Protocol/PlatformToDriverConfiguration.h> +#include <Protocol/DriverSupportedEfiVersion.h> +#include <Protocol/DriverFamilyOverride.h> +#include <Protocol/DriverHealth.h> +#include <Protocol/SimplePointer.h> +#include <Protocol/CpuIo2.h> +#include <Protocol/PciRootBridgeIo.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/SortLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/HiiLib.h> +#include <Library/FileHandleLib.h> +#include <Library/DevicePathLib.h> +#include <Library/PrintLib.h> +#include <Library/HandleParsingLib.h> + + +extern EFI_HII_HANDLE gShellDebug1HiiHandle; + +/** + Function returns a system configuration table that is stored in the + EFI System Table based on the provided GUID. + + @param[in] TableGuid A pointer to the table's GUID type. + @param[in, out] Table On exit, a pointer to a system configuration table. + + @retval EFI_SUCCESS A configuration table matching TableGuid was found. + @retval EFI_NOT_FOUND A configuration table matching TableGuid was not found. +**/ +EFI_STATUS +GetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + IN OUT VOID **Table + ); + +/** + Function for 'setsize' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSetSize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'comp' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunComp ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'mode' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMode ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'memmap' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMemMap ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'compress' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEfiCompress ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'decompress' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEfiDecompress ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'dmem' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDmem ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'loadpcirom' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunLoadPciRom ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'mm' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunMm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'setvar' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSetVar ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'sermode' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSerMode ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'bcfg' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunBcfg ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'pci' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunPci ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'smbiosview' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunSmbiosView ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'dmpstore' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDmpStore ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'dblk' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunDblk ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'edit' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunEdit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Function for 'hexedit' command. + + @param[in] ImageHandle Handle to the Image (NULL if Internal). + @param[in] SystemTable Pointer to the System Table (NULL if Internal). +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunHexEdit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Clear the line at the specified Row. + + @param[in] Row The row number to be cleared ( start from 1 ) + @param[in] LastCol The last printable column. + @param[in] LastRow The last printable row. +**/ +VOID +EditorClearLine ( + IN UINTN Row, + IN UINTN LastCol, + IN UINTN LastRow + ); + +/** + Check if file name has illegal characters. + + @param Name The filename to check. + + @retval TRUE The filename is ok. + @retval FALSE The filename is not ok. +**/ +BOOLEAN +IsValidFileName ( + IN CONST CHAR16 *Name + ); + +/** + Find a filename that is valid (not taken) with the given extension. + + @param[in] Extension The file extension. + + @retval NULL Something went wrong. + @return the valid filename. +**/ +CHAR16 * +EditGetDefaultFileName ( + IN CONST CHAR16 *Extension + ); + +/** + Read a file into an allocated buffer. The buffer is the responsibility + of the caller to free. + + @param[in] FileName The filename of the file to open. + @param[out] Buffer Upon successful return, the pointer to the + address of the allocated buffer. + @param[out] BufferSize If not NULL, then the pointer to the size + of the allocated buffer. + @param[out] ReadOnly Upon successful return TRUE if the file is + read only. FALSE otherwise. + + @retval EFI_NOT_FOUND The filename did not represent a file in the + file system. Directories cannot be read with + this method. + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_LOAD_ERROR The file read operation failed. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_INVALID_PARAMETER FileName was NULL. + @retval EFI_INVALID_PARAMETER FileName was a directory. +**/ +EFI_STATUS +ReadFileIntoBuffer ( + IN CONST CHAR16 *FileName, + OUT VOID **Buffer, + OUT UINTN *BufferSize OPTIONAL, + OUT BOOLEAN *ReadOnly + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf new file mode 100644 index 00000000..9a4459e9 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf @@ -0,0 +1,132 @@ +## @file +# Provides shell Debug1 profile functions +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = UefiShellDebug1CommandsLib + FILE_GUID = 90330D51-A99B-4cc8-A2EB-AE22542A3F45 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.2 + LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = UefiShellDebug1CommandsLibConstructor + DESTRUCTOR = UefiShellDebug1CommandsLibDestructor + +[Sources] + SetSize.c + Comp.c + Mode.c + MemMap.c + Compress.h + Compress.c + EfiCompress.c + EfiDecompress.c + Dmem.c + LoadPciRom.c + Mm.c + SetVar.c + SerMode.c + Pci.c + Pci.h + DmpStore.c + Dblk.c + SmbiosView/EventLogInfo.c + SmbiosView/EventLogInfo.h + SmbiosView/PrintInfo.c + SmbiosView/QueryTable.c + SmbiosView/SmbiosView.c + SmbiosView/SmbiosViewStrings.uni + SmbiosView/LibSmbiosView.c + SmbiosView/PrintInfo.h + SmbiosView/LibSmbiosView.h + SmbiosView/QueryTable.h + SmbiosView/SmbiosView.h + UefiShellDebug1CommandsLib.c + UefiShellDebug1CommandsLib.h + UefiShellDebug1CommandsLib.uni + +## Files shared by both editors + EditTitleBar.h + EditTitleBar.c + EditInputBar.h + EditInputBar.c + EditStatusBar.h + EditStatusBar.c + EditMenuBar.h + EditMenuBar.c + +## Files specific to the text editor + Edit/Edit.c + Edit/TextEditor.h + Edit/TextEditorTypes.h + Edit/FileBuffer.h + Edit/FileBuffer.c + Edit/MainTextEditor.h + Edit/MainTextEditor.c + Edit/Misc.h + Edit/Misc.c + Edit/TextEditStrings.uni + +## Files specific to the HEX editor + HexEdit/BufferImage.h + HexEdit/BufferImage.c + HexEdit/Clipboard.h + HexEdit/Clipboard.c + HexEdit/DiskImage.h + HexEdit/DiskImage.c + HexEdit/FileImage.h + HexEdit/FileImage.c + HexEdit/HexEdit.c + HexEdit/HexEditor.h + HexEdit/HexEditorTypes.h + HexEdit/HexeditStrings.uni + HexEdit/MainHexEditor.h + HexEdit/MainHexEditor.c + HexEdit/MemImage.h + HexEdit/MemImage.c + HexEdit/Misc.h + HexEdit/Misc.c + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + BaseMemoryLib + IoLib + DebugLib + ShellCommandLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + SortLib + PrintLib + BcfgCommandLib + +[Pcd] + gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize ## CONSUMES + gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES + +[Protocols] + gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiSimplePointerProtocolGuid ## SOMETIMES_CONSUMES + gEfiCpuIo2ProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## GUID + gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiMpsTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gShellDebug1HiiGuid ## SOMETIMES_CONSUMES ## HII diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni new file mode 100644 index 00000000..6693be26 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni @@ -0,0 +1,1173 @@ +// /**
+//
+// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+// (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
+// (C) Copyright 2016 - 2019 Hewlett Packard Enterprise Development LP<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// UefiShellDebug1CommandsLib.uni
+//
+// Abstract:
+//
+// String definitions for UEFI Shell 2.0 Debug1 profile commands
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "english"
+
+#string STR_GEN_NO_MEM #language en-US "%H%s%N: Memory is not available.\r\n"
+#string STR_GEN_BOOT_ONLY #language en-US "%H%s%N: Boot must be selected for hot key options.\r\n"
+#string STR_GEN_FIND_FAIL #language en-US "%H%s%N: File not found - '%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_PROBLEM_VAL #language en-US "%H%s%N: Bad value - '%H%s%N' for flag - '%H%s%N'\r\n"
+#string STR_GEN_DUPLICATE #language en-US "%H%s%N: Duplicate flag - '%H%s%N'\r\n"
+#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
+#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments.\r\n"
+#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n"
+#string STR_GEN_NO_DRIVER_BOOT #language en-US "%H%s%N: Driver or Boot must be selected.\r\n"
+#string STR_GEN_PCIRBIO_NF #language en-US "%H%s%N: Protocol - PciRootBridgeIo not found.\r\n"
+#string STR_GEN_PCIRBIO_ER #language en-US "%H%s%N: Problem accessing the data using Protocol - PciRootBridgeIo\r\n"
+#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n"
+#string STR_GEN_PARAM_INV_HEX #language en-US "%H%s%N: Invalid parameter - '%H%s%N'. Must be hexadecimal.\r\n"
+#string STR_GEN_PARAM_CONFLICT #language en-US "%H%s%N: Flags conflict with - '%H%s%N' and '%H%s%N'\r\n"
+#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
+#string STR_GEN_MAP_PROTOCOL #language en-US "%H%s%N: Mapped device '%B%s%N' does not have protocol %B%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_FILE_DELETE_FAIL #language en-US "%H%s%N: Cannot delete file - '%H%s%N'\r\n"
+#string STR_GEN_NO_CWD #language en-US "%H%s%N: Current directory not specified.\r\n"
+#string STR_GEN_FILE_IS_DIRECTORY #language en-US "%H%s%N: The file '%H%s%N' is a directory.\r\n"
+#string STR_GEN_SFO_HEADER #language en-US "ShellCommand,"%s"\r\n"
+
+
+#string STR_FILE_OPEN_FAIL #language en-US "Unable to open file on '%B%s%N' with: %r.\r\n"
+#string STR_FILE_FIND_FAIL #language en-US "%H%s%N: File not found - '%H%s%N'\r\n"
+#string STR_FILE_NOT_DIR #language en-US "%H%s%N: Directories are not permitted - '%H%s%N'\r\n"
+#string STR_SIZE_NOT_SPEC #language en-US "%H%s%N: A valid size must be specified\r\n"
+#string STR_FILE_NOT_SPEC #language en-US "%H%s%N: File not specified\r\n"
+#string STR_FILE_WRITE_FAIL #language en-US "%H%s%N: Write file error - '%H%s%N'\r\n"
+#string STR_FILE_READ_FAIL #language en-US "%H%s%N: Read file error - '%H%s%N'\r\n"
+#string STR_VOLUME_FULL #language en-US "%H%s%N: The volume is full\r\n"
+
+#string STR_SET_SIZE_FAIL #language en-US "%H%s%N: Unable to change size on '%B%s%N'\r\n"
+#string STR_SET_SIZE_DONE #language en-US "Size changed on '%B%s%N'.\r\n"
+
+#string STR_DBLK_HEADER #language en-US "LBA %016LX Size %08x bytes BlkIo %0x\r\n"
+
+#string STR_COMP_HEADER #language en-US "Compare %s to %s.\r\n"
+#string STR_COMP_DIFFERENCE_POINT #language en-US "Difference #% 2u:\r\n"
+#string STR_COMP_END_OF_FILE #language en-US " <EOF>"
+
+#string STR_COMP_FOOTER_FAIL #language en-US "[difference(s) encountered] \r\n"
+#string STR_COMP_FOOTER_PASS #language en-US "[no differences encountered]\r\n"
+
+#string STR_MODE_SET_FAIL #language en-US "%H%s%N: Unable to change the mode.\r\n"
+#string STR_MODE_NO_MATCH #language en-US "%H%s%N: No matching mode found to set\r\n"
+#string STR_MODE_LIST_HEAD #language en-US "Available modes for console output device.\r\n"
+#string STR_MODE_LIST_ITEM #language en-US " Col % 5d Row % 5d %c\r\n"
+
+#string STR_MEMMAP_GET_FAILED #language en-US "%H%s%N: Unable to get memory map\r\n"
+#string STR_MEMMAP_LIST_HEAD #language en-US "Type Start End # Pages Attributes\r\n"
+#string STR_MEMMAP_LIST_ITEM #language en-US "% -10s %016LX-%016LX %016LX %016LX\r\n"
+#string STR_MEMMAP_LIST_ITEM_OTHER #language en-US "%08x %016LX-%016LX %016LX %016LX\r\n"
+#string STR_MEMMAP_LIST_SUMM #language en-US " \r\n"
+ " Reserved : %,14ld Pages (%,ld Bytes)\r\n"
+ " LoaderCode: %,14ld Pages (%,ld Bytes)\r\n"
+ " LoaderData: %,14ld Pages (%,ld Bytes)\r\n"
+ " BS_Code : %,14ld Pages (%,ld Bytes)\r\n"
+ " BS_Data : %,14ld Pages (%,ld Bytes)\r\n"
+ " RT_Code : %,14ld Pages (%,ld Bytes)\r\n"
+ " RT_Data : %,14ld Pages (%,ld Bytes)\r\n"
+ " ACPI_Recl : %,14ld Pages (%,ld Bytes)\r\n"
+ " ACPI_NVS : %,14ld Pages (%,ld Bytes)\r\n"
+ " MMIO : %,14ld Pages (%,ld Bytes)\r\n"
+ " MMIO_Port : %,14ld Pages (%,ld Bytes)\r\n"
+ " PalCode : %,14ld Pages (%,ld Bytes)\r\n"
+ " Available : %,14ld Pages (%,ld Bytes)\r\n"
+ " Persistent: %,14ld Pages (%,ld Bytes)\r\n"
+#string STR_MEMMAP_LIST_SUMM_OTHER #language en-US " %08x : %,14ld Pages (%,ld Bytes)\r\n"
+#string STR_MEMMAP_LIST_SUMM2 #language en-US " -------------- \r\n"
+ "Total Memory: %,14ld MB (%,ld Bytes)\r\n"
+#string STR_MEMMAP_LIST_ITEM_SFO #language en-US "MemoryMap,"%s","%LX","%LX","%LX","%LX"\r\n"
+#string STR_MEMMAP_LIST_SUMM_SFO #language en-US "MemoryMapSummary,"%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld","%Ld"\r\n"
+
+#string STR_EFI_COMPRESS_FAIL #language en-US "Unable to compress: %r.\r\n"
+#string STR_EFI_DECOMPRESS_FAIL #language en-US "Unable to decompress: %r.\r\n"
+#string STR_EFI_DECOMPRESS_NOPE #language en-US "The file does not appear to be a compressed file. Cannot continue. \"%H%s%N\"\r\n"
+
+#string STR_DMEM_HEADER_ROW #language en-US "Memory Address %016LX %X Bytes\r\n"
+#string STR_DMEM_MMIO_HEADER_ROW #language en-US "Memory Mapped IO Address %016LX %X Bytes\r\n"
+#string STR_DMEM_DATA_ROW #language en-US "%08X: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x *%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c*\r\n"
+#string STR_DMEM_SYSTEM_TABLE #language en-US "\r\nValid EFI Header at Address %016Lx\r\n"
+ "---------------------------------------------\r\n"
+ "System: Table Structure size %08x revision %08x\r\n"
+ "ConIn (%016LX) ConOut (%016LX) StdErr (%016LX)\r\n"
+ "Runtime Services %016LX\r\n"
+ "Boot Services %016LX\r\n"
+ "SAL System Table %016LX\r\n"
+ "ACPI Table %016LX\r\n"
+ "ACPI 2.0 Table %016LX\r\n"
+ "MPS Table %016LX\r\n"
+ "SMBIOS Table %016LX\r\n"
+
+#string STR_LOAD_PCI_ROM_RES #language en-US "Image '%B%s%N' load result: %r\r\n"
+#string STR_LOADPCIROM_CORRUPT #language en-US "%H%s%N: File '%B%s%N' Image %d is corrupt.\r\n"
+#string STR_LOADPCIROM_LOAD_FAIL #language en-US "%H%s%N: File '%B%s%N' Image %d unable to load.\r\n"
+#string STR_LOADPCIROM_START_FAIL #language en-US "%H%s%N: File '%B%s%N' Image %d unable to start.\r\n"
+
+#string STR_MM_NOT_ALIGNED #language en-US "%H%s%N: Address parameter %016LX is not aligned.\r\n"
+#string STR_MM_PCIE_ADDRESS_RANGE #language en-US "%H%s%N: Address parameter %016LX is not a valid PCI/PCIE address.\r\n"
+#string STR_MM_MMIO #language en-US "%HMMIO%N"
+#string STR_MM_IO #language en-US "%HIO%N"
+#string STR_MM_PCI #language en-US "%HPCI%N"
+#string STR_MM_MEM #language en-US "%HMEM%N"
+#string STR_MM_PCIE #language en-US "%HPCIE%N"
+#string STR_MM_ADDRESS #language en-US " 0x%016lx : "
+#string STR_MM_BUF #language en-US "0x%0*lx"
+#string STR_MM_ERROR #language en-US "%H%s%N: Input had incorrect format\r\n"
+
+#string STR_SETVAR_PRINT #language en-US "%g - %s - %04x Bytes\r\n"
+#string STR_SETVAR_ERROR_SET #language en-US "%H%s%N: Unable to set - %H%g%N - %H%s%N\r\n"
+#string STR_SETVAR_ERROR_GET #language en-US "%H%s%N: Unable to get - %H%g%N - %H%s%N\r\n"
+#string STR_SETVAR_ERROR_DPFT #language en-US "%H%s%N: DevicePathFromText conversion was not successful.\r\n"
+
+#string STR_SERMODE_NO_FOUND #language en-US "%H%s%N: No serial ports found.\r\n"
+#string STR_SERMODE_NOT_FOUND #language en-US "%H%s%N: No serial port or specified serial port found.\r\n"
+#string STR_SERMODE_BAD_HANDLE #language en-US "%H%s%N: Handle %H%02x%N is not a serial device handle.\r\n"
+#string STR_SERMODE_SET_HANDLE #language en-US "Mode set on handle %H%02x%N successfully.\r\n"
+#string STR_SERMODE_SET_FAIL #language en-US "%H%s%N: Mode change on handle %H%02x%N was not successful.\r\n"
+#string STR_SERMODE_DISPLAY #language en-US "%x(%08x) - (%ld, %c, %d, %s)\r\n"
+#string STR_SERMODE_SET_UNSUPPORTED #language en-US "%H%s%N: One or more of the new settings is not supported on handle %H%02x%N.\r\n"
+#string STR_SERMODE_SET_DEV_ERROR #language en-US "%H%s%N: The serial device on handle %H%02x%N is not functioning correctly.\r\n"
+
+#string STR_PCI_HANDLE_CFG_ERR #language en-US "%H%s%N: Handle protocol or configuration error.\r\n"
+#string STR_PCI_BUS_RANGE_ERR #language en-US "%H%s%N: Get next bus range error.\r\n"
+#string STR_PCI_NO_FIND #language en-US "%H%s%N: Cannot find protocol interface for segment %x, bus %x.\r\n"
+#string STR_PCI_NO_CFG #language en-US "%H%s%N: Cannot read configuration data.\r\n"
+#string STR_PCI_INFO #language en-US "%H PCI Segment %02x Bus %02x Device %02x Func %02x%N [EFI %02x%02x%02x%02x00]\r\n"
+#string STR_PCI_TITLE #language en-US " Seg Bus Dev Func\r\n"
+ " --- --- --- ----\r\n"
+#string STR_PCI_LINE_P1 #language en-US " %E%02x %02x %02x %02x ==> %N"
+#string STR_PCI_LINE_P2 #language en-US "\r\n Vendor %04x Device %04x Prog Interface %x\r\n"
+#string STR_PCIEX_CAPABILITY_CAPID #language en-US "CapID(%2x): %E%02x%N"
+#string STR_PCIEX_NEXTCAP_PTR #language en-US " NextCap Ptr(%2x): %E%02x%N\r\n"
+#string STR_PCIEX_CAP_REGISTER #language en-US "Cap Register(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_DEVICE_CAP #language en-US "Device Capabilities(%2x): %E%08x%N\r\n"
+#string STR_PCIEX_DEVICE_CONTROL #language en-US "Device Control(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_DEVICE_STATUS #language en-US "Device Status(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_LINK_CAPABILITIES #language en-US "Link Capabilities(%2x): %E%08x%N\r\n"
+#string STR_PCIEX_LINK_CONTROL #language en-US "Link Control(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_LINK_STATUS #language en-US "Link Status(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_SLOT_CAPABILITIES #language en-US "Slot Capabilities(%2x): %E%08x%N\r\n"
+#string STR_PCIEX_SLOT_CONTROL #language en-US "Slot Control(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_SLOT_STATUS #language en-US "Slot Status(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_ROOT_CONTROL #language en-US "Root Control(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_RSVDP #language en-US "Root Capabilities(%2x): %E%04x%N\r\n"
+#string STR_PCIEX_ROOT_STATUS #language en-US "Root Status(%2x): %E%08x%N\r\n"
+#string STR_PCI_LINE_VID_DID #language en-US "Vendor ID(%x): %E%04x%N Device ID(%x): %E%04x%N\r\n"
+#string STR_PCI_LINE_RID #language en-US "Revision ID(%x): %E%02x%N "
+#string STR_PCI_LINE_BIST #language en-US "BIST(%02x): "
+#string STR_PCI_LINE_CAP #language en-US "Capable,Return: %E%02x%N\r\n"
+#string STR_PCI_LINE_CAP_NO #language en-US " Incapable\r\n"
+#string STR_PCI2_CACHE_LINE_SIZE #language en-US "Cache Line Size(%x): %E%02x%N "
+#string STR_PCI2_LATENCY_TIMER #language en-US "Latency Timer(%x): %E%02x%N\r\n"
+#string STR_PCI2_HEADER_TYPE #language en-US "Header Type(%02x): %E%02x%N, "
+#string STR_PCI2_MULTI_FUNCTION #language en-US "Multi-function, "
+#string STR_PCI2_SINGLE_FUNCTION #language en-US "Single function, "
+#string STR_PCI2_PCI_DEVICE #language en-US "PCI device\r\n"
+#string STR_PCI2_P2P_BRIDGE #language en-US "P2P bridge\r\n"
+#string STR_PCI2_CARDBUS_BRIDGE #language en-US "CardBus bridge\r\n"
+#string STR_PCI2_RESERVED #language en-US "Reserved\r\n"
+#string STR_PCI2_CLASS #language en-US "Class: "
+#string STR_PCI2_BASE_ADDR #language en-US "Base Address Registers(%x):\r\n"
+#string STR_PCI2_START_TYPE #language en-US " Start_Address Type Space Prefetchable? Size Limit\r\n"
+#string STR_PCI2_NONE #language en-US " (None)"
+#string STR_PCI2_EXPANSION_ROM_DISABLED #language en-US "\r\nExpansion ROM Disabled(%x)\r\n\r\n"
+#string STR_PCI2_EXPANSION_ROM_BASE #language en-US "\r\nExpansion ROM Base Address(%x): %E%08x%N\r\n\r\n"
+#string STR_PCI2_CARDBUS_CIS #language en-US "Cardbus CIS ptr(%x): %E%08x%N\r\n"
+#string STR_PCI2_SUB_VENDOR_ID #language en-US "Sub VendorID(%x): %E%04x%N "
+#string STR_PCI2_SUBSYSTEM_ID #language en-US "Subsystem ID(%x): %E%04x%N\r\n"
+#string STR_PCI2_CAPABILITIES_PTR #language en-US "Capabilities Ptr(%x): %E%02x%N\r\n"
+#string STR_PCI2_INTERRUPT_LINE #language en-US "Interrupt Line(%x): %E%02x%N "
+#string STR_PCI2_INTERRUPT_PIN #language en-US "Interrupt Pin(%x): %E%02x%N\r\n"
+#string STR_PCI2_MIN_GNT #language en-US "Min_Gnt(%x): %E%02x%N "
+#string STR_PCI2_MAX_LAT #language en-US "Max_Lat(%x): %E%02x%N\r\n"
+#string STR_PCI2_BASE_ADDRESS #language en-US "Base Address Registers(%x):"
+#string STR_PCI2_START_TYPE_2 #language en-US " Start_Address Type Space Prefetchable? Size Limit\r\n"
+#string STR_PCI2_NO_EXPANSION_ROM #language en-US "\r\nNo Expansion ROM(%x) "
+#string STR_PCI2_EXPANSION_ROM_BASE_2 #language en-US "\r\nExpansion ROM Base Address(%x): %E%08x%N\r\n"
+#string STR_PCI2_BUS_NUMBERS #language en-US "\r\n\r\n(Bus Numbers) Primary(%x) Secondary(%x) Subordinate(%x)\r\n"
+#string STR_PCI2_BRIDGE #language en-US " %E%02x%N"
+#string STR_PCI2_SECONDARY_TIMER #language en-US "\r\nSecondary Latency Timer(%x): %E%02x%N\n\n"
+#string STR_PCI2_CARDBUS_LATENCY #language en-US "\r\nCardBus Latency Timer(%x): %E%02x%N\r\n"
+#string STR_PCI2_RESOURCE_TYPE_2 #language en-US "\r\nResource Type Type Base Limit\r\n"
+#string STR_PCI2_MEM_3 #language en-US "Mem(%x) %s %E%08x%N %E%08x%N\r\n"
+#string STR_PCI2_IO_2 #language en-US "I/O(%x) %s %E%08x%N %E%08x%N\r\n"
+#string STR_PCI2_INTERRUPT_LINE_3 #language en-US "\r\nInterrupt Line(%x): %E%02x%N Interrupt Pin(%x): %E%02x%N\r\n"
+#string STR_PCI2_SUB_VENDOR_ID_2 #language en-US "\r\nSub VendorID(%x): %E%04x%N Subsystem ID(%x): %E%04x%N\r\n"
+#string STR_PCI2_OPTIONAL #language en-US "Optional 16-Bit PC Card legacy Mode Base Address(%x): %E%08x%N\r\n"
+#string STR_PCI2_STATUS #language en-US "Status(%x): %E%04x%N\r\n"
+#string STR_PCI2_SECONDARY_STATUS #language en-US "Secondary Status(%2x): %E%4x%N\r\n"
+#string STR_PCI2_NEW_CAPABILITIES #language en-US " (04)New Capabilities linked list: %E%d%N"
+#string STR_PCI2_66_CAPABLE #language en-US " (05)66MHz Capable: %EN/A%N\r\n"
+#string STR_PCI2_66_CAPABLE_2 #language en-US " (05)66MHz Capable: %E%d%N\r\n"
+#string STR_PCI2_FAST_BACK #language en-US " (07)Fast Back-to-Back Capable: %E%d%N"
+#string STR_PCI2_NO #language en-US "No "
+#string STR_PCI2_YES #language en-US "YES "
+#string STR_PCI2_ONE_VAR_4 #language en-US "\r\n %E%04x%N "
+#string STR_PCI2_NEWBAR_32 #language en-US " %08x "
+#string STR_PCI2_NEWBAR_32_2 #language en-US " %08x"
+#string STR_PCI2_RSHIFT #language en-US "%08x"
+#string STR_PCI2_NEWBAR_32_3 #language en-US "%04x "
+#string STR_PCI2_NEWBAR_32_4 #language en-US "%04x"
+#string STR_PCI2_CARDBUS_SOCKET #language en-US "\r\nCardBus Socket Registers/ExCA Base Address Register(%x): %E%8x%N\r\n\r\n"
+#string STR_PCI2_BUS_NUMBERS_2 #language en-US "\r\n(Bus Numbers) Pci(%x) CardBus(%x) Subordinate(%x)\r\n"
+#string STR_PCI2_CARDBUS #language en-US " %E%02x%N"
+#string STR_PCI2_CARDBUS_2 #language en-US " %E%02x%N"
+#string STR_PCI2_CARDBUS_3 #language en-US " %E%02x%N\r\n"
+#string STR_PCI2_MASTER_DATA #language en-US " (08)Master Data Parity Error: %E%d%N\r\n"
+#string STR_PCI2_DEVSEL_TIMING #language en-US " (09)DEVSEL timing: "
+#string STR_PCI2_FAST #language en-US "%E Fast%N"
+#string STR_PCI2_MEDIUM #language en-US "%E Medium%N"
+#string STR_PCI2_SLOW #language en-US "%E Slow%N"
+#string STR_PCI2_RESERVED_2 #language en-US "%EReserved%N"
+#string STR_PCI2_SIGNALED_TARGET #language en-US " (11)Signaled Target Abort: %E%d%N\r\n"
+#string STR_PCI2_RECEIVED_TARGET #language en-US " (12)Received Target Abort: %E%d%N"
+#string STR_PCI2_RECEIVED_MASTER #language en-US " (13)Received Master Abort: %E%d%N\r\n"
+#string STR_PCI2_SIGNALED_ERROR #language en-US " (14)Signaled System Error: %E%d%N"
+#string STR_PCI2_RECEIVED_ERROR #language en-US " (14)Received System Error: %E%d%N"
+#string STR_PCI2_DETECTED_ERROR #language en-US " (15)Detected Parity Error: %E%d%N\r\n"
+#string STR_PCI2_COMMAND #language en-US "Command(%x): %E%04x%N\r\n"
+#string STR_PCI2_SPACE_ACCESS_DENIED #language en-US " (00)I/O space access enabled: %E%d%N"
+#string STR_PCI2_MEMORY_SPACE #language en-US " (01)Memory space access enabled: %E%d%N\r\n"
+#string STR_PCI2_BEHAVE_BUS_MASTER #language en-US " (02)Behave as bus master: %E%d%N"
+#string STR_PCI2_MONITOR_SPECIAL_CYCLE #language en-US " (03)Monitor special cycle enabled: %E%d%N\r\n"
+#string STR_PCI2_MEM_WRITE_INVALIDATE #language en-US " (04)Mem Write & Invalidate enabled: %E%d%N"
+#string STR_PCI2_PALETTE_SNOOPING #language en-US " (05)Palette snooping is enabled: %E%d%N\r\n"
+#string STR_PCI2_ASSERT_PERR #language en-US " (06)Assert PERR# when parity error: %E%d%N"
+#string STR_PCI2_DO_ADDR_STEPPING #language en-US " (07)Do address/data stepping: %E%d%N\r\n"
+#string STR_PCI2_SERR_DRIVER #language en-US " (08)SERR# driver enabled: %E%d%N"
+#string STR_PCI2_FAST_BACK_2 #language en-US " (09)Fast back-to-back transact...: %E%d%N\r\n\r\n"
+#string STR_PCI2_BRIDGE_CONTROL #language en-US "Bridge Control(%x) %E%04x%N\r\n"
+#string STR_PCI2_PARITY_ERROR #language en-US " (00)Parity Error Response: %E%d%N"
+#string STR_PCI2_SERR_ENABLE #language en-US " (01)SERR# Enable: %E%d%N\r\n"
+#string STR_PCI2_ISA_ENABLE #language en-US " (02)ISA Enable: %E%d%N"
+#string STR_PCI2_RESOURCE_TYPE #language en-US "\r\nResource Type Base Limit\r\n"
+#string STR_PCI2_TWO_VARS #language en-US "I/O(%x) %E%08x%N"
+#string STR_PCI2_ONE_VAR #language en-US " %E%08x%N\r\n"
+#string STR_PCI2_MEMORY #language en-US "Memory(%x) %E%08x%N"
+#string STR_PCI2_PREFETCHABLE #language en-US "Prefetchable Memory(%x) %E%08x%08x%N"
+#string STR_PCI2_TWO_VARS_2 #language en-US " %E%08x%08x%N\r\n"
+#string STR_PCI2_CAPABILITIES_PTR_2 #language en-US "\r\nCapabilities Ptr(%x): %E%02x%N \r\n\r\n"
+#string STR_PCI2_INTERRUPT_LINE_2 #language en-US "\r\nInterrupt Line(%x) %E%02x%N "
+#string STR_PCI2_BAR #language en-US "\r\n %E%08x%N "
+#string STR_PCI2_MEM #language en-US "Mem "
+#string STR_PCI2_32_BITS #language en-US "32 bits "
+#string STR_PCI2_ONE_VAR_2 #language en-US "\r\n %E%08x"
+#string STR_PCI2_ONE_VAR_3 #language en-US "%08x%N "
+#string STR_PCI2_64_BITS #language en-US "64 bits "
+#string STR_PCI2_MEM_2 #language en-US "Mem "
+#string STR_PCI2_VGA_ENABLE #language en-US " (03)VGA Enable: %E%d%N\r\n"
+#string STR_PCI2_MASTER_ABORT #language en-US " (05)Master Abort Mode: %E%d%N"
+#string STR_PCI2_SECONDARY_BUS_RESET #language en-US " (06)Secondary Bus Reset: %E%d%N\r\n"
+#string STR_PCI2_FAST_ENABLE #language en-US " (07)Fast Back-to-Back Enable: %E%d%N"
+#string STR_PCI2_PRIMARY_DISCARD_TIMER #language en-US " (08)Primary Discard Timer: %E%s%N\r\n"
+#string STR_PCI2_SECONDARY_DISCARD_TIMER #language en-US " (09)Secondary Discard Timer: %E%s%N"
+#string STR_PCI2_DISCARD_TIMER_STATUS #language en-US " (10)Discard Timer Status: %E%d%N\r\n"
+#string STR_PCI2_DISCARD_TIMER_SERR #language en-US " (11)Discard Timer SERR# Enable: %E%d%N\r\n"
+#string STR_PCI2_CARDBUS_RESET #language en-US " (06)CardBus Reset: %E%d%N\r\n"
+#string STR_PCI2_IREQ_ENABLE #language en-US " (07)IREQ/INT Enable: %E%d%N"
+#string STR_PCI2_WRITE_POSTING_ENABLE #language en-US " (10)Write Posting Enable: %E%d%N\r\n"
+#string STR_PCI_EXT_CAP_AER #language en-US " Advanced Error Reporting\r\n"
+ " UncorrectableErrorStatus %08x\r\n"
+ " UncorrectableErrorMask %08x\r\n"
+ " UncorrectableErrorSeverity %08x\r\n"
+ " CorrectableErrorStatus %08x\r\n"
+ " CorrectableErrorMask %08x\r\n"
+ " AdvancedErrorCapAndControl %08x\r\n"
+ " HeaderLog1 %08x\r\n"
+ " HeaderLog2 %08x\r\n"
+ " HeaderLog3 %08x\r\n"
+ " HeaderLog4 %08x\r\n"
+ " RootErrorCommand %08x\r\n"
+ " RootErrorStatus %08x\r\n"
+ " ErrorSourceIdentification %04x\r\n"
+ " CorrectableErrorSourceIden %04x\r\n"
+ " TlpPrefixLog1 %08x\r\n"
+ " TlpPrefixLog2 %08x\r\n"
+ " TlpPrefixLog3 %08x\r\n"
+ " TlpPrefixLog4 %08x\r\n"
+#string STR_PCI_EXT_CAP_LINK_CONTROL #language en-US " Link Control\r\n"
+ " RootComplexLinkCapabilities %08x\r\n"
+ " RootComplexLinkControl %04x\r\n"
+ " RootComplexLinkStatus %04x\r\n"
+#string STR_PCI_EXT_CAP_LINK_DECLAR #language en-US " Link Declaration\r\n"
+ " ElementSelfDescription %08x\r\n"
+#string STR_PCI_EXT_CAP_LINK_DECLAR2 #language en-US " LinkEntry[%x] %08x\r\n"
+#string STR_PCI_EXT_CAP_SN #language en-US " Serial Number\r\n"
+ " SerialNumber %L16x\r\n"
+#string STR_PCI_EXT_CAP_POWER #language en-US " Power Budgeting\r\n"
+ " DataSelect %02x\r\n"
+ " Data %08x\r\n"
+ " PowerBudgetCapability %02x\r\n"
+#string STR_PCI_EXT_CAP_ACS #language en-US " ACS\r\n"
+ " CapabilityRegister %04x\r\n"
+ " ControlRegister %04x\r\n"
+#string STR_PCI_EXT_CAP_ACS2 #language en-US " EgressControlVectorByte[%x] %02x\r\n"
+#string STR_PCI_EXT_CAP_LAT #language en-US " Latency Tolerance Reporting\r\n"
+ " MaxSnoopLatency %04x\r\n"
+ " MaxNoSnoopLatency %04x\r\n"
+#string STR_PCI_EXT_CAP_ARI #language en-US " ARI\r\n"
+ " AriCapability %04x\r\n"
+ " AriControl %04x\r\n"
+#string STR_PCI_EXT_CAP_RCRB #language en-US " RCRB\r\n"
+ " VendorId %04x\r\n"
+ " DeviceId %04x\r\n"
+ " RcrbCapabilities %04x\r\n"
+ " RcrbControl %04x\r\n"
+#string STR_PCI_EXT_CAP_VEN #language en-US " VendorSpecific\r\n"
+ " VendorSpecificHeader %04x\r\n"
+#string STR_PCI_EXT_CAP_DPA #language en-US " DPA\r\n"
+ " DpaCapability %04x\r\n"
+ " DpaLatencyIndicator %04x\r\n"
+ " DpaStatus %04x\r\n"
+ " DpaControl %04x\r\n"
+#string STR_PCI_EXT_CAP_DPA2 #language en-US " DpaPowerAllocationArray[%x] %02x\r\n"
+#string STR_PCI_EXT_CAP_ECEA #language en-US " Event Collector Endpoint Association\r\n"
+ " AssociationBitmap %04x\r\n"
+#string STR_PCI_EXT_CAP_VC_BASE #language en-US " Virtual (Multi) Channel Capability\r\n"
+ " ExtendedVcCount %08x\r\n"
+ " PortCapability1 %08x\r\n"
+ " PortCapability2 %08x\r\n"
+ " ArbitrationTableOffset %08x\r\n"
+ " PortVcControl %04x\r\n"
+ " PortVcStatus %04x\r\n"
+#string STR_PCI_EXT_CAP_VC_ITEM #language en-US " Virtual Channel Capability Extended Item[%x]\r\n"
+ " ResourceCapability %08x\r\n"
+ " ArbitrationTableOffset %08x\r\n"
+ " ResourceControl %08x\r\n"
+ " ResourceStatus %04x\r\n"
+#string STR_PCI_EXT_CAP_MULTICAST #language en-US " MultiCast Capability\r\n"
+ " MultiCastCapability %04x\r\n"
+ " MulticastControl %04x\r\n"
+ " McBaseAddress %L16x\r\n"
+ " McReceiveAddress %L16x\r\n"
+ " McBlockAll %L16x\r\n"
+ " McBlockUntranslated %L16x\r\n"
+ " McOverlayBar %L16x\r\n"
+#string STR_PCI_EXT_CAP_RESIZE_BAR #language en-US " Resizeable Bar Capability [%x]\r\n"
+ " ResizableBarCapability %08x\r\n"
+ " ResizableBarControl %04x\r\n"
+#string STR_PCI_EXT_CAP_TPH #language en-US " TPH\r\n"
+ " TphRequesterCapability %08x\r\n"
+ " TphRequesterControl %04x\r\n"
+ " TphTable (optional):\r\n"
+#string STR_PCI_EXT_CAP_SECONDARY #language en-US " Secondary PCI Express Extended Capability\r\n"
+ " LinkControl3 %08x\r\n"
+ " LaneErrorStatus %08x\r\n"
+ " EqualizationControl:\r\n"
+
+#string STR_DMPSTORE_SAVE #language en-US "Save variable to file: %H%s%N.\r\n"
+#string STR_DMPSTORE_LOAD #language en-US "Load and set variables from file: %H%s%N.\r\n"
+#string STR_DMPSTORE_LOAD_GEN_FAIL #language en-US "%H%s%N: Failed to set variable %H%s%N: %r.\r\n"
+#string STR_DMPSTORE_LOAD_BAD_FILE #language en-US "%H%s%N: Incorrect file format.\r\n"
+#string STR_DMPSTORE_HEADER_LINE #language en-US "Variable %H%s%N '%H%g%N:%H%s%N' DataSize = 0x%02x\r\n"
+#string STR_DMPSTORE_HEADER_LINE2 #language en-US "Variable %H%s%N '%H%s%N:%H%s%N' DataSize = 0x%02x\r\n"
+#string STR_DMPSTORE_DELETE_LINE #language en-US "Delete variable '%H%g%N:%H%s%N': %r\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND #language en-US "%H%s%N: No matching variables found.\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_SFO #language en-US "VariableInfo,\"\",\"\",\"\",\"\",\"\"\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_GN #language en-US "%H%s%N: No matching variables found. Guid %g, Name %s\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_NG_SFO #language en-US "VariableInfo,\"%s\",\"%g\",\"\",\"\",\"\"\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_N #language en-US "%H%s%N: No matching variables found. Name %s\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_N_SFO #language en-US #language en-US "VariableInfo,\"%s\",\"\",\"\",\"\",\"\"\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_G #language en-US "%H%s%N: No matching variables found. Guid %g\r\n"
+#string STR_DMPSTORE_NO_VAR_FOUND_G_SFO #language en-US "VariableInfo,\"\",\"%g\",\"\",\"\",\"\"\r\n"
+#string STR_DMPSTORE_VAR_SFO #language en-US "VariableInfo,\"%s\",\"%g\",\"0x%x\",\"0x%x\",\"%s\"\r\n"
+
+#string STR_GET_HELP_COMP #language en-US ""
+".TH comp 0 "Compare 2 files"\r\n"
+".SH NAME\r\n"
+"Compares the contents of two files on a byte-for-byte basis.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"COMP [-b] file1 file2\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -b - Displays one screen at a time.\r\n"
+" file1 - Specifies a first file name (directory name or wildcards not permitted).\r\n"
+" file2 - Specifies a second file name (directory name or wildcards not permitted).\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command compares the contents of two files in binary mode.\r\n"
+" 2. It displays up to 10 differences between the two files. For each\r\n"
+" difference, up to 32 bytes from the location where the difference starts\r\n"
+" is dumped.\r\n"
+" 3. It will exit immediately if the lengths of the compared files are\r\n"
+" different.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To compare two files with the same length but different contents:\r\n"
+" fs0:\> comp bios.inf bios2.inf\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The function operated as expected.\r\n"
+" SHELL_NOT_EQUAL The files were not identical.\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"
+" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
+" violation.\r\n"
+" SHELL_NOT_FOUND The requested file was not found.\r\n"
+
+#string STR_GET_HELP_SETSIZE #language en-US ""
+".TH setsize 0 "Set file size"\r\n"
+".SH NAME\r\n"
+"Adjusts the size of a file.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"SETSIZE size file [file...]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" size - Specifies the size of the file after it is adjusted.\r\n"
+" file - Specifies the file or files to be adjusted.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. Setting the size smaller than the actual data contained in this file will\r\n"
+" truncate its data.\r\n"
+" 2. This command adjusts the size of a particular target file.\r\n"
+" 3. This command automatically truncates or extends the size of a file based on the passed-in\r\n"
+" parameters. If the file does not exist, it is created.\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The action was completed as requested.\r\n"
+" SHELL_VOLUME_FULL The media has insufficient space to complete the\r\n"
+" request.\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"
+
+#string STR_GET_HELP_MODE #language en-US ""
+".TH mode 0 "Shows or changes ConOut mode."\r\n"
+".SH NAME\r\n"
+"Displays or changes the console output device mode.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"MODE [col row]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" col - Specifies the number of columns.\r\n"
+" row - Specifies the number of rows.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command changes the display mode for the console output\r\n"
+" device.\r\n"
+" 2. When this command is used without any parameters, it shows the list of\r\n"
+" modes that the standard output device currently supports.\r\n"
+" 3. When used with the row and col parameter, this command\r\n"
+" changes the number of rows and columns on the standard output device.\r\n"
+" 4. The current selected mode is indicated by a '*'. \r\n"
+" 5. The display is cleared every time this command is used to change the\r\n"
+" currently selected display mode.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display all available modes on standard output:\r\n"
+" Shell> mode\r\n"
+" \r\n"
+" * To change the current mode setting:\r\n"
+" Shell> mode 80 50\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The action was completed as requested.\r\n"
+" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
+" violation.\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"
+
+#string STR_GET_HELP_MEMMAP #language en-US ""
+".TH memmap 0 "Displays the memory map."\r\n"
+".SH NAME\r\n"
+"Displays the memory map maintained by the UEFI environment.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"MEMMAP [-b] [-sfo]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -b - Displays one screen at a time\r\n"
+" -sfo - Displays information as described in Standard-Format Output.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. The UEFI environment keeps track of all the physical memory in the system\r\n"
+" and how it is currently being used.\r\n"
+" 2. Total Memory is the physical memory size excluding Reserved, Unusable,\r\n"
+" MemoryMappedIO, and MemoryMappedIOPortSpace memory types.\r\n"
+" 3. Refer to the UEFI specification for memory type definitions.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display the system memory map:\r\n"
+" Shell> memmap\r\n"
+" \r\n"
+
+#string STR_GET_HELP_EFICOMPRESS #language en-US ""
+".TH eficompress 0 "compresses a file."\r\n"
+".SH NAME\r\n"
+"Compresses a file using UEFI Compression Algorithm.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"EFICOMPRESS infile outfile\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" infile - Specifies the file name of the uncompressed input file.\r\n"
+" outfile - Specifies the file name of the compressed output file.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command compresses a file using UEFI Compression Algorithm\r\n"
+" and writes the compressed form out to a new file.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To compress a file named 'uncompressed' to a file named 'compressed':\r\n"
+" fs0:\> eficompress uncompressed compressed\r\n"
+
+#string STR_GET_HELP_EFIDCOMPRESS #language en-US ""
+".TH efidecompress 0 "Decompresses a file."\r\n"
+".SH NAME\r\n"
+"Decompresses a file using UEFI Decompression Algorithm.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"EFIDECOMPRESS infile outfile\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" infile - Specifies the file name of the compressed input file.\r\n"
+" outfile - Specifies the file name of the decompressed output file.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This decompresses a file using UEFI Decompression\r\n"
+" Algorithm and writes the decompressed form out to a new file.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To decompress a file named 'compressed' to a file named 'uncompressed':\r\n"
+" fs0:\> efidecompress compressed uncompressed\r\n"
+
+#string STR_GET_HELP_DMEM #language en-US ""
+".TH dmem 0 "Displays memory."\r\n"
+".SH NAME\r\n"
+"Displays the contents of system or device memory.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"DMEM [-b] [address] [size] [-MMIO]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -b - Displays one screen at a time.\r\n"
+" -MMIO - Forces address cycles to the PCI bus.\r\n"
+" address - Specifies a starting address in hexadecimal format.\r\n"
+" size - Specifies the number of bytes to display in hexadecimal format.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command displays the contents of system memory or device memory.\r\n"
+" 2. Enter address and size in hexadecimal format.\r\n"
+" 3. If address is not specified, the contents of the UEFI System Table\r\n"
+" are displayed. Otherwise, memory starting at the specified address is displayed.\r\n"
+" 4. Size specifies the number of bytes to display. If size is not specified,\r\n"
+" 512 bytes are displayed.\r\n"
+" 5. If MMIO is not specified, main system memory is displayed. Otherwise,\r\n"
+" device memory is displayed through the use of the\r\n"
+" EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display the UEFI system table pointer entries:\r\n"
+" fs0:\> dmem\r\n"
+" \r\n"
+" * To display memory contents from 1af3088 with size of 16 bytes:\r\n"
+" Shell> dmem 1af3088 16\r\n"
+" \r\n"
+" * To display memory mapped IO contents from 1af3088 with a size of 16 bytes:\r\n"
+" Shell> dmem 1af3088 16 -MMIO\r\n"
+
+#string STR_GET_HELP_MM #language en-US ""
+".TH mm 0 "Displays or modifies address space memory."\r\n"
+".SH NAME\r\n"
+"Displays or modifies MEM/MMIO/IO/PCI/PCIE address space.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"MM Address [Value] [-w 1|2|4|8] [-MEM | -MMIO | -IO | -PCI | -PCIE] [-n]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" Address - Starting address in hexadecimal format.\r\n"
+" Value - The value to write in hexadecimal format.\r\n"
+" -MEM - Memory Address type\r\n"
+" -MMIO - Memory Mapped IO Address type\r\n"
+" -IO - IO Address type\r\n"
+" -PCI - PCI Configuration Space Address type:\r\n"
+" Address format: ssssbbddffrr\r\n"
+" ssss - Segment\r\n"
+" bb - Bus\r\n"
+" dd - Device\r\n"
+" ff - Function\r\n"
+" rr - Register\r\n"
+" -PCIE - PCIE Configuration Space Address type:\r\n"
+" Address format: ssssbbddffrrr\r\n"
+" ssss - Segment\r\n"
+" bb - Bus\r\n"
+" dd - Device\r\n"
+" ff - Function\r\n"
+" rrr - Register\r\n"
+" -w - Unit size accessed in bytes:\r\n"
+" 1 - 1 byte\r\n"
+" 2 - 2 bytes\r\n"
+" 4 - 4 bytes\r\n"
+" 8 - 8 bytes\r\n"
+" -n - Non-interactive mode\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. If the address type parameter is not specified, address type defaults\r\n"
+" to the 'MEM' type.\r\n"
+" 2. If the 'Value' parameter is specified, the '-n' option is used and\r\n"
+" the command writes the value to the\r\n"
+" specified address in non-interactive mode. If the 'Value' parameter is\r\n"
+" not specified, only the current contents in the address are displayed.\r\n"
+" 3. If the '-w' option is not specified, unit size defaults to 1 byte.\r\n"
+" 4. If the PCI address type is specified, the 'Address' parameter must\r\n"
+" follow the PCI Configuration Space Address format above. The 'PCI'\r\n"
+" command can be used to determine the address for a specified device.\r\n"
+" It is listed in the PCI configuration space dump information in the\r\n"
+" following format: "[EFI ssbbddffxx]".\r\n"
+" 5. If the PCIE address type is specified, the 'Address' parameter must\r\n"
+" follow the PCIE Configuration Space Address format above.\r\n"
+" 6. In interactive mode, type a hex value to modify, 'q' or '.' to exit.\r\n"
+" If the '-n' option is specified, it runs in non-interactive mode,\r\n"
+" which supports batch file operation without user intervention.\r\n"
+" 7. Not all PCI configuration register locations are writable.\r\n"
+" 8. MM will only write the specified value. Read-modify-write operations\r\n"
+" are not supported.\r\n"
+" 9. The 'Address' parameter must be aligned on a boundary of the\r\n"
+" specified width.\r\n"
+" 10. Not all addresses are safe to access. Access to any improper address\r\n"
+" can bring unexpected results.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display or modify memory:\r\n"
+" Address 0x1b07288, default width=1 byte:\r\n"
+" fs0:\> mm 1b07288\r\n"
+" MEM 0x0000000001B07288 : 0x6D >\r\n"
+" MEM 0x0000000001B07289 : 0x6D >\r\n"
+" MEM 0x0000000001B0728A : 0x61 > 80\r\n"
+" MEM 0x0000000001B0728B : 0x70 > q\r\n"
+" fs0:\> mm 1b07288\r\n"
+" MEM 0x0000000001B07288 : 0x6D >\r\n"
+" MEM 0x0000000001B07289 : 0x6D >\r\n"
+" MEM 0x0000000001B0728A : 0x80 > *Modified\r\n"
+" MEM 0x0000000001B0728B : 0x70 > q\r\n"
+" \r\n"
+" * To modify memory: Address 0x1b07288, width = 2 bytes:\r\n"
+" Shell> mm 1b07288 -w 2\r\n"
+" MEM 0x0000000001B07288 : 0x6D6D >\r\n"
+" MEM 0x0000000001B0728A : 0x7061 > 55aa\r\n"
+" MEM 0x0000000001B0728C : 0x358C > q\r\n"
+" Shell> mm 1b07288 -w 2\r\n"
+" MEM 0x0000000001B07288 : 0x6D6D >\r\n"
+" MEM 0x0000000001B0728A : 0x55AA > *Modified\r\n"
+" MEM 0x0000000001B0728C : 0x358C > q\r\n"
+" \r\n"
+" * To display IO space: Address 80h, width = 4 bytes:\r\n"
+" Shell> mm 80 -w 4 -IO\r\n"
+" IO 0x0000000000000080 : 0x000000FE >\r\n"
+" IO 0x0000000000000084 : 0x00FF5E6D > q\r\n"
+" \r\n"
+" * To modify IO space using non-interactive mode:\r\n"
+" Shell> mm 80 52 -w 1 -IO\r\n"
+" Shell> mm 80 -w 1 -IO\r\n"
+" IO 0x0000000000000080 : 0x52 > FE *Modified\r\n"
+" IO 0x0000000000000081 : 0xFF >\r\n"
+" IO 0x0000000000000082 : 0x00 >\r\n"
+" IO 0x0000000000000083 : 0x00 >\r\n"
+" IO 0x0000000000000084 : 0x6D >\r\n"
+" IO 0x0000000000000085 : 0x5E >\r\n"
+" IO 0x0000000000000086 : 0xFF >\r\n"
+" IO 0x0000000000000087 : 0x00 > q\r\n"
+" \r\n"
+" * To display PCI configuration space, ss=0000, bb=00, dd=00, ff=00, rr=00:\r\n"
+" Shell> mm 000000000000 -PCI\r\n"
+" PCI 0x0000000000000000 : 0x86 >\r\n"
+" PCI 0x0000000000000001 : 0x80 >\r\n"
+" PCI 0x0000000000000002 : 0x30 >\r\n"
+" PCI 0x0000000000000003 : 0x11 >\r\n"
+" PCI 0x0000000000000004 : 0x06 >\r\n"
+" PCI 0x0000000000000005 : 0x00 > q\r\n"
+" These contents can also be displayed by 'PCI 00 00 00'.\r\n"
+" \r\n"
+" * To display PCIE configuration space, ss=0000, bb=06, dd=00, ff=00, rrr=000:\r\n"
+" Shell> mm 0000060000000 -PCIE\r\n"
+" PCIE 0x0000000060000000 : 0xAB >\r\n"
+" PCIE 0x0000000060000001 : 0x11 >\r\n"
+" PCIE 0x0000000060000002 : 0x61 >\r\n"
+" PCIE 0x0000000060000003 : 0x43 >\r\n"
+" \r\n"
+
+#string STR_GET_HELP_LOAD_PCI_ROM #language en-US ""
+".TH loadpcirom 0 "Loads a PCI option ROM file."\r\n"
+".SH NAME\r\n"
+"Loads a PCI Option ROM.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"LoadPciRom [-nc] romfile [romfile...]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -nc - Loads the ROM image(s) but does not connect drivers.\r\n"
+" romfile - Specifies the PCI option ROM image file (wildcards are permitted).\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command loads PCI option ROM images into memory for\r\n"
+" execution.\r\n"
+" 2. The file can contain legacy images and multiple PE32 images, in which case\r\n"
+" all PE32 images are loaded.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To load a rom file 'rom.bin':\r\n"
+" fs0:\> LoadPciRom rom.bin\r\n"
+" \r\n"
+" * To load '*.bin' files without connecting drivers:\r\n"
+" fs0:\> LoadPciRom -nc *.bin\r\n"
+
+#string STR_GET_HELP_SETVAR #language en-US ""
+".TH setvar 0 "Displays or modifies a UEFI variable."\r\n"
+".SH NAME\r\n"
+"Displays or modifies a UEFI variable.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"SETVAR variable-name [-guid guid][-bs][-rt][-nv] [=data]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" variable-name - Specifies the name of the UEFI variable to modify or display.\r\n"
+" -guid - Specifies the GUID of the UEFI variable to modify or display.\r\n"
+" If not present, GUID EFI_GLOBAL_VARIABLE is assumed.\r\n"
+" -bs - Indicates that the variable is a boot variable. Applies to a new variable;\r\n"
+" otherwise, it is ignored. \r\n"
+" -rt - Indicates that the variable is a runtime variable. Applies to a new variable;\r\n"
+" otherwise, it is ignored. \r\n"
+" -nv - Indicates that the variable is non-volatile. If not present,\r\n"
+" then the variable is assumed to be volatile. Applies to a new variable;\r\n"
+" otherwise, it is ignored. \r\n"
+" =data - Specifies there is new data for the variable. If there is nothing after the '='\r\n"
+" then the variable is deleted. If '=' is not present, then the\r\n"
+" current value of the variable is dumped as hex bytes.\r\n"
+" The data can consist of zero or more of the following:\r\n"
+" xx[xx] - Hexadecimal bytes\r\n"
+" ^"ascii-string^" - ASCII-string with no null-terminator\r\n"
+" L^"UCS2-string^" - UCS-2 encoded string with no\r\n"
+" null-terminator\r\n"
+" --device - Device path text format\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command changes the UEFI variable specified by name and GUID.\r\n"
+" 2. If = is specified, but data is not, the variable is deleted, if it exists.\r\n"
+" 3. If = is not specified, then the current variable contents are displayed.\r\n"
+" 4. If =data is specified, then the variable's value is changed to the value\r\n"
+" specified by data.\r\n"
+" 5. -bs, -rt and -nv are only useful if the variable does not exist.\r\n"
+" 6. If the variable already exists, the attributes cannot be changed, and the"
+" flags will be ignored.\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The shell has stored the variable and its data with\r\n"
+" the defined attributes.\r\n"
+" SHELL_INVALID_PARAMETER Incorrect attributes were used.\r\n"
+" SHELL_OUT_OF_RESOURCES Insufficient resources were available for storing\r\n"
+" the variable and its data.\r\n"
+" SHELL_DEVICE_ERROR The Variable could not be saved due to a hardware\r\n"
+" error.\r\n"
+" SHELL_WRITE_PROTECTED The variable in question is read-only.\r\n"
+" SHELL_WRITE_PROTECTED The variable in question cannot be deleted.\r\n"
+" SHELL_NOT_FOUND The variable could not be found.\r\n"
+
+#string STR_GET_HELP_SERMODE #language en-US ""
+".TH sermode 0 "configure serial port"\r\n"
+".SH NAME\r\n"
+"Sets serial port attributes.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"SERMODE [handle [baudrate parity databits stopbits]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" handle - Specifies a device handle for a serial port in hexadecimal format.\r\n"
+" baudrate - Specifies a baud rate for specified serial port.\r\n"
+" parity - Sets parity bit settings for specified serial port. Valid values\r\n"
+" are:\r\n"
+" d - Default parity\r\n"
+" n - No parity\r\n"
+" e - Even parity\r\n"
+" o - Odd parity\r\n"
+" m - Mark parity\r\n"
+" s - Space parity\r\n"
+" databits - Sets the data bits for the specified serial port.\r\n"
+" stopbits - Sets the stop bits for the specified serial port.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. The 'handle' parameter is the device handle of the desired serial port.\r\n"
+" The 'DH' command can be used to retrieve this information.\r\n"
+" 2. The 'stopbits' parameter supports the following settings:\r\n"
+" 0 (0 stop bits - default setting)\r\n"
+" 1 (1 stop bit)\r\n"
+" 2 (2 stop bits)\r\n"
+" 15 (1.5 stop bits)\r\n"
+" All other settings are invalid.\r\n"
+" 3. The 'baudrate' parameter supports the following settings:\r\n"
+" 50, 75, 110, 150, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800,\r\n"
+" 7200, 9600(default), 19200, 38400, 57600, 115200, 230400, 460800\r\n"
+" All other values will be converted to the next highest setting.\r\n"
+" 4. The 'databits' parameter supports the following settings:\r\n"
+" 4\r\n"
+" 7\r\n"
+" 8 (default)\r\n"
+" All other settings are invalid.\r\n"
+" 5. Parity attributes are mutually exclusive.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display the settings for all serial port devices:\r\n"
+" Shell> sermode\r\n"
+" \r\n"
+" * To display the settings for the serial port device whose handle is 0x6B:\r\n"
+" Shell> sermode 6B\r\n"
+" \r\n"
+" * To configure the serial port settings for handle 0x6B to 9600bps, even\r\n"
+" parity, 8 data bits, and 1 stop bit:\r\n"
+" Shell> sermode 6B 9600 e 8 1\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The new attributes were set on the serial device.\r\n"
+" SHELL_INVALID_PARAMETER One or more of the attributes has an unsupported\r\n"
+" value.\r\n"
+" SHELL_DEVICE_ERROR The serial device is not functioning correctly.\r\n"
+
+#string STR_GET_HELP_PCI #language en-US ""
+".TH pci 0 "Displays PCI device information."\r\n"
+".SH NAME\r\n"
+"Displays PCI device list or PCI function configuration space and PCIe extended\r\n"
+"configuration space.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"PCI [Bus Dev [Func] [-s Seg] [-i [-ec ID]]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -s - Specifies optional segment number (hexadecimal number).\r\n"
+" -i - Displays interpreted information.\r\n"
+" -ec - Displays detailed interpretation of specified PCIe extended capability\r\n"
+" ID (hexadecimal number).\r\n"
+" Bus - Specifies a bus number (hexadecimal number).\r\n"
+" Dev - Specifies a device number (hexadecimal number).\r\n"
+" Func - Specifies a function number (hexadecimal number).\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command displays a list of all the PCI devices found in the system. It\r\n"
+" also displays the configuration space of a PCI device according to the\r\n"
+" specified bus (Bus), device (Dev), and function (Func) addresses. If the\r\n"
+" function address is not specified, it defaults to 0.\r\n"
+" 2. The -i option displays verbose information for the specified PCI\r\n"
+" device. The PCI configuration space for the device is displayed with\r\n"
+" a detailed interpretation.\r\n"
+" 3. If no parameters are specified, all PCI devices are listed.\r\n"
+" 4. If the 'Bus' and 'Dev' parameters are specified but the 'Func' or\r\n"
+" 'Seg' parameters are not, Function or Seg are set to the default value of 0.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display all PCI devices in the system:\r\n"
+" Shell> pci\r\n"
+" \r\n"
+" * To display the configuration space of Bus 0, Device 0, Function 0:\r\n"
+" Shell> pci 00 00 00 -i\r\n"
+" \r\n"
+" * To display configuration space of Segment 0, Bus 0, Device 0, Function 0:\r\n"
+" Shell> pci 00 00 00 -s 0\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS Data was displayed as requested.\r\n"
+" SHELL_DEVICE_ERROR The specified device parameters did not match a physical\r\n"
+" device in the system.\r\n"
+
+#string STR_GET_HELP_SMBIOSVIEW #language en-US ""
+".TH smbiosview 0 "Displays SMBIOS information."\r\n"
+".SH NAME\r\n"
+"Displays SMBIOS information.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"SMBIOSVIEW [-t SmbiosType]|[-h SmbiosHandle]|[-s]|[-a]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -t - Displays all structures of SmbiosType.\r\n"
+" -h - Displays structure of SmbiosHandle.\r\n"
+" -s - Displays a statistics table.\r\n"
+" -a - Displays all information.\r\n"
+" SmbiosType - Specifies a SMBIOS structure type.\r\n"
+" SmbiosHandle - Specifies a SMBIOS structure unique 16-bit handle.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. The SmbiosType parameter supports the following types:\n"
+" 0 - BIOS Information\r\n"
+" 1 - System Information\r\n"
+" 2 - Baseboard Information\r\n"
+" 3 - System Enclosure\r\n"
+" 4 - Processor Information\r\n"
+" 5 - Memory Controller Information\r\n"
+" 6 - Memory Module Information\r\n"
+" 7 - Cache Information\r\n"
+" 8 - Port Connector Information\r\n"
+" 9 - System Slots\r\n"
+" 10 - On Board Devices Information\r\n"
+" 11 - OEM Strings\r\n"
+" 12 - System Configuration Options\r\n"
+" 13 - BIOS Language Information\r\n"
+" 14 - Group Associations\r\n"
+" 15 - System Event Log\r\n"
+" 16 - Physical Memory Array\r\n"
+" 17 - Memory Device\r\n"
+" 18 - 32-bit Memory Error Information\r\n"
+" 19 - Memory Array Mapped Address\r\n"
+" 20 - Memory Device Mapped Address\r\n"
+" 21 - Built-in Pointing Device\r\n"
+" 22 - Portable Battery\r\n"
+" 23 - System Reset\r\n"
+" 24 - Hardware Security\r\n"
+" 25 - System Power Controls\r\n"
+" 26 - Voltage Probe\r\n"
+" 27 - Cooling Device\r\n"
+" 28 - Temperature Probe\r\n"
+" 29 - Electrical Current Probe\r\n"
+" 30 - Out-Of-Band Remote Access\r\n"
+" 31 - Boot Integrity Services (BIS) Entry Point\r\n"
+" 32 - System Boot Information\r\n"
+" 33 - 64-Bit Memory Error Information\r\n"
+" 34 - Management Device\r\n"
+" 35 - Management Device Component\r\n"
+" 36 - Management Device Threshold Data\r\n"
+" 37 - Memory Channel\r\n"
+" 38 - IPMI Device Information\r\n"
+" 39 - System Power Supply\r\n"
+" 40 - Additional Information\r\n"
+" 41 - Onboard Devices Extended Information\r\n"
+" 42 - Management Controller Host Interface\r\n"
+" 43 - TPM Device\r\n"
+" 44 - Processor Additional Information\r\n"
+" 2. Enter the SmbiosHandle parameter in hexadecimal format.\r\n"
+" Do not use the '0x' prefix format for hexadecimal values.\r\n"
+" 3. Internal commands:\r\n"
+" :q -------- quit smbiosview\r\n"
+" :0 -------- Change smbiosview display NONE info\r\n"
+" :1 -------- Change smbiosview display OUTLINE info\r\n"
+" :2 -------- Change smbiosview display NORMAL info\r\n"
+" :3 -------- Change smbiosview display DETAIL info\r\n"
+" /? -------- Show help\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS Data was displayed as requested.\r\n"
+" SHELL_DEVICE_ERROR The requested structure was not found.\r\n"
+
+#string STR_GET_HELP_DMPSTORE #language en-US ""
+".TH dmpstore 0 "Manages all UEFI variables."\r\n"
+".SH NAME\r\n"
+"Manages all UEFI variables.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"DMPSTORE [-b] [-d] [-all | ([variable] [-guid guid])] [-sfo]\r\n"
+"DMPSTORE [-all | ([variable] [-guid guid])] [-s file]\r\n"
+"DMPSTORE [-all | ([variable] [-guid guid])] [-l file]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -b - Displays one screen at a time.\r\n"
+" -guid - Specifies the GUID of the variables to be displayed in\r\n"
+" standard text format. If not specified and -all is not\r\n"
+" specified, the EFI_GLOBAL_VARIABLE GUID is assumed.\r\n"
+" -sfo - Displays information as described in Standard-Format Output.\r\n"
+" -all - Dumps all variables, including those\r\n"
+" with a different GUID than EFI_GLOBAL_VARIABLE.\r\n"
+" -d - Delete variables.\r\n"
+" -s - Saves variables to a file.\r\n"
+" -l - Loads and sets variables from a file.\r\n"
+" variable - Specifies a variable name. This can be a literal name or\r\n"
+" a pattern as specified in the MetaiMatch() function of the\r\n"
+" EFI_UNICODE_COLLATION2_PROCOOL.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command manages the UEFI variables. The variables\r\n"
+" displayed or deleted depend on the command line options, as specified in\r\n"
+" the following table:\r\n"
+" Variable GUID -all Description\r\n"
+" --- --- --- All variables with the GUID EFI_GLOBAL_VARIABLE will\r\n"
+" be operated on.\r\n"
+" --- --- X All variables (regardless of GUID or name) will be\r\n"
+" operated on.\r\n"
+" --- X --- All variables with the specified GUID will be\r\n"
+" operated on.\r\n"
+" X --- --- The variable with the GUID EFI_GLOBAL_VARIABLE and\r\n"
+" the name Variable will be operated on.\r\n"
+" X X --- The variable with the specified GUID and name\r\n"
+" Variable will be operated on.\r\n"
+" 2. The variable value is printed as a hexadecimal dump.\r\n"
+" 3. Option -d is used to delete variables. Option -s and -l are used to save\r\n"
+" and load variables to and from a file. The variable name can be specified\r\n"
+" when using these flags so that the operation only takes effect on\r\n"
+" that variable.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To dump all variables with the GUID EFI_GLOBAL_VARIABLE:\r\n"
+" Shell> dmpstore\r\n"
+" \r\n"
+" * To dump all variables (regardless of GUID or name):\r\n"
+" Shell> dmpstore -all\r\n"
+" \r\n"
+" * To dump the 'path' variable with the GUID '158DEF5A-F656-419C-B027-\r\n"
+" 7A3192C079D2':\r\n"
+" Shell> dmpstore path -guid 158DEF5A-F656-419C-B027-7A3192C079D2\r\n"
+" \r\n"
+" * To save all variables (regardless of GUID or name) to a file 'VarDump.txt':\r\n"
+" fs0:\> dmpstore -all -s VarDump.txt\r\n"
+" \r\n"
+" * To delete the 'BootOrder' variable with the GUID EFI_GLOBAL_VARIABLE:\r\n"
+" Shell> dmpstore -d BootOrder\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"
+
+#string STR_GET_HELP_DBLK #language en-US ""
+".TH dblk 0 "Displays one or more blocks from a block device."\r\n"
+".SH NAME\r\n"
+"Displays one or more blocks from a block device.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"DBLK device [lba] [blocks] [-b]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -b - Displays one screen at a time.\r\n"
+" device - Blocks the device name.\r\n"
+" lba - Specifies the index of the first block to be displayed (a hexadecimal number).\r\n"
+" The default is 0.\r\n"
+" blocks - Specifies the number of blocks to display (a hexadecimal number). The default\r\n"
+" is 1. If larger than 0x10, then only 0x10 are displayed.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command displays the contents of one or more blocks from a block\r\n"
+" device. Enter a hexidecimal value for the lba and blocks variables. If lba is not\r\n"
+" specified, block #0 is assumed. If blocks is not specified, on1y one\r\n"
+" block is displayed. The maximum number of blocks that can be\r\n"
+" displayed at one time is 0x10.\r\n"
+" 2. If an MBR is found on the block, the partition information is displayed\r\n"
+" after all the block contents are displayed.\r\n"
+" 3. If the block is a FAT partition, some FAT parameters are displayed\r\n"
+" (label, systemid, oemid, sectorsize, clustersize, media, and so forth) after all the\r\n"
+" blocks are displayed.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display one block of blk0, beginning from block 0:\r\n"
+" Shell> dblk blk0\r\n"
+" \r\n"
+" * To display one block of fs0, beginning from block 0x2:\r\n"
+" Shell> dblk fs0 2\r\n"
+" \r\n"
+" * To display 0x5 blocks of fs0, beginning from block 0x12:\r\n"
+" Shell> dblk fs0 12 5\r\n"
+" \r\n"
+" * To display 0x10 blocks of fs0, beginning from block 0x12:\r\n"
+" Shell> dblk fs0 12 10\r\n"
+" \r\n"
+" * To attempt to display more than 0x10 blocks, resulting in only 0x10\r\n"
+" blocks being displayed:\r\n"
+" Shell> dblk fs0 12 20\r\n"
+" \r\n"
+" * To display one block of blk2, beginning from the first block (blk0):\r\n"
+" fs1:\tmps1> dblk blk2 0 1\r\n"
+" \r\n"
+
+#string STR_GET_HELP_EDIT #language en-US ""
+".TH edit 0 "Provides a full screen text editor for ASCII or UCS-2 files."\r\n"
+".SH NAME\r\n"
+"Provides a full screen text editor for ASCII or UCS-2 files.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"EDIT [file]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" file - Specifies the name of file to be edited. If none is specified, an empty file\r\n"
+" is created with a default file name.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command enables full screen file editing.\r\n"
+" 2. The editor supports both UCS-2 and ASCII file types.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To edit the 'shell.log' file:\r\n"
+" fs0:\> edit shell.log\r\n"
+
+#string STR_GET_HELP_HEXEDIT #language en-US ""
+".TH hexedit 0 "Provides a full screen hex editor for files, block devices, or memory."\r\n"
+".SH NAME\r\n"
+"Provides a full screen hex editor for files, block devices, or memory.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"HEXEDIT [[-f] filename| [-d diskname offset size] | [-m address size]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -f - Specifies the name of the file to edit.\r\n"
+" -d - Specifies the disk block to edit:\r\n"
+" DiskName - Name of the disk to edit (for example fs0)\r\n"
+" Offset - Starting block number (beginning from 0)\r\n"
+" Size - Number of blocks to edit\r\n"
+" -m - Specifies the memory region to edit:\r\n"
+" Address - Starting 32-bit memory address (beginning from 0)\r\n"
+" Size - Size of memory region to edit in bytes\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command enables you to edit a file, block device, or memory region.\r\n"
+" 2. The region being edited is displayed as hexadecimal bytes. The\r\n"
+" contents can be modified and saved.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To edit a file in hex mode:\r\n"
+" fs0:\> hexedit test.bin\r\n"
+" \r\n"
+" * To edit block device fs0 starting at block 0 with size of 2 blocks:\r\n"
+" fs0:\> hexedit -d fs0 0 2\r\n"
+" \r\n"
+" * To edit memory region starting at address 0x00000000 with size of 2 bytes:\r\n"
+" fs0:\> hexedit -m 0 2\r\n"
+
|