Beispiel #1
0
/**
  Add a command to the mCmdTable. If there is no free space in the command
  table ASSERT. The mCmdTable is maintained in alphabetical order and the
  new entry is inserted into its sorted position.

  @param  Entry   Command Entry to add to the CmdTable

**/
VOID
EFIAPI
EblAddCommand (
  IN const EBL_COMMAND_TABLE   *Entry
  )
{
  UINTN               Count;

  if (mCmdTableNextFreeIndex == EBL_MAX_COMMAND_COUNT) {
    //
    // Ran out of space to store commands. Increase EBL_MAX_COMMAND_COUNT
    //
    ASSERT (FALSE);
    return;
  }

  //
  // Add command and Insertion sort array in the process
  //
  mCmdTable[mCmdTableNextFreeIndex] = (EBL_COMMAND_TABLE *)Entry;
  if (mCmdTableNextFreeIndex != 0) {
    for (Count = mCmdTableNextFreeIndex; Count > 0; Count--) {
      if (AsciiStriCmp (mCmdTable[Count - 1]->Name, Entry->Name) <= 0) {
        break;
      }

      mCmdTable[Count] = mCmdTable[Count - 1];
    }
    mCmdTable[Count] = (EBL_COMMAND_TABLE *)Entry;
  }

  mCmdTableNextFreeIndex++;
}
Beispiel #2
0
/**
  List out help information on all the commands or print extended information
  about a specific passed in command.

  Argv[0] - "help"
  Argv[1] - Command to display help about

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblHelpCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN   Index;
  CHAR8   *Ptr;
  UINTN   CurrentRow = 0;

  if (Argc == 1) {
    // Print all the commands
    AsciiPrint ("Embedded Boot Loader (EBL) commands (help command for more info):\n");
    CurrentRow++;
    for (Index = 0; Index < mCmdTableNextFreeIndex; Index++) {
      EblSetTextColor (EFI_YELLOW);
      AsciiPrint (" %a", mCmdTable[Index]->Name);
      EblSetTextColor (0);
      AsciiPrint ("%a\n", mCmdTable[Index]->HelpSummary);
      // Handle multi line help summaries
      CurrentRow += CountNewLines (mCmdTable[Index]->HelpSummary);
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
        break;
      }
    }
  } else if (Argv[1] != NULL) {
    // Print specific help
    for (Index = 0, CurrentRow = 0; Index < mCmdTableNextFreeIndex; Index++) {
      if (AsciiStriCmp (Argv[1], mCmdTable[Index]->Name) == 0) {
        Ptr = (mCmdTable[Index]->Help == NULL) ? mCmdTable[Index]->HelpSummary : mCmdTable[Index]->Help;
        AsciiPrint ("%a%a\n", Argv[1], Ptr);
        // Handle multi line help summaries
        CurrentRow += CountNewLines (Ptr);
        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
          break;
        }
      }
    }
  }

  return EFI_SUCCESS;
}
Beispiel #3
0
/**

  Check whether the HTTP message is using the "chunked" transfer-coding.

  @param[in]    HeaderCount        Number of HTTP header structures in Headers.
  @param[in]    Headers            Array containing list of HTTP headers.

  @return       The message is "chunked" transfer-coding (TRUE) or not (FALSE).
 
**/
BOOLEAN
HttpIoIsChunked (
  IN   UINTN                    HeaderCount,
  IN   EFI_HTTP_HEADER          *Headers
  )
{
  EFI_HTTP_HEADER       *Header;


  Header = HttpIoFindHeader (HeaderCount, Headers, "Transfer-Encoding");
  if (Header == NULL) {
    return FALSE;
  }

  if (AsciiStriCmp (Header->FieldValue, "identity") != 0) {
    return TRUE;
  }

  return FALSE;
}
Beispiel #4
0
/**
  Return the best matching command for the passed in command name. The match
  does not have to be exact, it just needs to be unique. This enables commands
  to be shortened to the smallest set of starting characters that is unique.

  @param  CommandName   Name of command to search for

  @return NULL  CommandName did not match or was not unique
          Other Pointer to EBL_COMMAND_TABLE entry for CommandName

**/
EBL_COMMAND_TABLE *
EblGetCommand (
  IN CHAR8    *CommandName
  )
{
  UINTN               Index;
  UINTN               BestMatchCount;
  UINTN               Length;
  EBL_COMMAND_TABLE   *Match;
  CHAR8               *Str;

  Length = AsciiStrLen (CommandName);
  Str = AsciiStrStr (CommandName, ".");
  if (Str != NULL) {
    // If the command includes a trailing . command extension skip it for the match.
    // Example: hexdump.4
    Length = (UINTN)(Str - CommandName);
  }

  for (Index = 0, BestMatchCount = 0, Match = NULL; Index < mCmdTableNextFreeIndex; Index++) {
    if (AsciiStriCmp (mCmdTable[Index]->Name,  CommandName) == 0) {
      // match a command exactly
      return mCmdTable[Index];
    }

    if (AsciiStrniCmp (CommandName, mCmdTable[Index]->Name, Length) == 0)  {
      // partial match, so keep looking to make sure there is only one partial match
      BestMatchCount++;
      Match = mCmdTable[Index];
    }
  }

  if (BestMatchCount == 1) {
    return Match;
  }

  //
  // We had no matches or too many matches
  //
  return NULL;
}
Beispiel #5
0
/**
  Find a specified header field according to the field name.

  @param[in]   HeaderCount      Number of HTTP header structures in Headers list. 
  @param[in]   Headers          Array containing list of HTTP headers.
  @param[in]   FieldName        Null terminated string which describes a field name. 

  @return    Pointer to the found header or NULL.

**/
EFI_HTTP_HEADER *
HttpIoFindHeader (
  IN  UINTN                HeaderCount,
  IN  EFI_HTTP_HEADER      *Headers,
  IN  CHAR8                *FieldName
  )
{
  UINTN                 Index;
  
  if (HeaderCount == 0 || Headers == NULL || FieldName == NULL) {
    return NULL;
  }

  for (Index = 0; Index < HeaderCount; Index++){
    //
    // Field names are case-insensitive (RFC 2616).
    //
    if (AsciiStriCmp (Headers[Index].FieldName, FieldName) == 0) {
      return &Headers[Index];
    }
  }
  return NULL;
}
Beispiel #6
0
/**
Internal work function to fill in EFI_OPEN_FILE information for the FV

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFvFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                          Status;
  EFI_STATUS                          GetNextFileStatus;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  UINTN                               Key;
  UINT32                              AuthenticationStatus;
  CHAR8                               AsciiSection[MAX_PATHNAME];
  VOID                                *Section;
  UINTN                               SectionSize;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  EFI_LBA                             Lba;
  UINTN                               BlockSize;
  UINTN                               NumberOfBlocks;
  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader = NULL;
  UINTN                               Index;


  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Get FVB Info about the handle
  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
  if (!EFI_ERROR (Status)) {
    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
    if (!EFI_ERROR (Status)) {
      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
      File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
      for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) {
        File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
      }

      for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
        if (EFI_ERROR (Status)) {
          break;
        }
      }
    }
  }


  DevicePath = DevicePathFromHandle (File->EfiHandle);

  if (*FileName == '\0') {
    File->DevicePath = DuplicateDevicePath (DevicePath);
    File->Size = File->FvSize;
    File->MaxPosition = File->Size;
  } else {
    Key = 0;
    do {
      File->FvType = EFI_FV_FILETYPE_ALL;
      GetNextFileStatus = File->Fv->GetNextFile (
        File->Fv,
        &Key,
        &File->FvType,
        &File->FvNameGuid,
        &File->FvAttributes,
        &File->Size
        );
      if (!EFI_ERROR (GetNextFileStatus)) {
        // Compare GUID first
        Status = CompareGuidToString (&File->FvNameGuid, FileName);
        if (!EFI_ERROR(Status)) {
          break;
        }

        Section = NULL;
        Status = File->Fv->ReadSection (
          File->Fv,
          &File->FvNameGuid,
          EFI_SECTION_USER_INTERFACE,
          0,
          &Section,
          &SectionSize,
          &AuthenticationStatus
          );
        if (!EFI_ERROR (Status)) {
          UnicodeStrToAsciiStr (Section, AsciiSection);
          if (AsciiStriCmp (FileName, AsciiSection) == 0) {
            FreePool (Section);
            break;
          }
          FreePool (Section);
        }
      }
    } while (!EFI_ERROR (GetNextFileStatus));

    if (EFI_ERROR (GetNextFileStatus)) {
      return GetNextFileStatus;
    }

    if (OpenMode != EFI_SECTION_ALL) {
      // Calculate the size of the section we are targeting
      Section = NULL;
      File->Size = 0;
      Status = File->Fv->ReadSection (
        File->Fv,
        &File->FvNameGuid,
        (EFI_SECTION_TYPE)OpenMode,
        0,
        &Section,
        &File->Size,
        &AuthenticationStatus
        );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    File->MaxPosition = File->Size;
    EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
    File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
  }


  // FVB not required if FV was soft loaded...
  return EFI_SUCCESS;
}
Beispiel #7
0
/**
  This function returns the image type according to server replied HTTP message
  and also the image's URI info.

  @param[in]    Uri              The pointer to the image's URI string.
  @param[in]    UriParser        URI Parse result returned by NetHttpParseUrl(). 
  @param[in]    HeaderCount      Number of HTTP header structures in Headers list. 
  @param[in]    Headers          Array containing list of HTTP headers.
  @param[out]   ImageType        The image type of the downloaded file.
  
  @retval EFI_SUCCESS            The image type is returned in ImageType.
  @retval EFI_INVALID_PARAMETER  ImageType, Uri or UriParser is NULL.
  @retval EFI_INVALID_PARAMETER  HeaderCount is not zero, and Headers is NULL.
  @retval EFI_NOT_FOUND          Failed to identify the image type.
  @retval Others                 Unexpect error happened.

**/
EFI_STATUS
HttpBootCheckImageType (
  IN      CHAR8                  *Uri,
  IN      VOID                   *UriParser,
  IN      UINTN                  HeaderCount,
  IN      EFI_HTTP_HEADER        *Headers,
     OUT  HTTP_BOOT_IMAGE_TYPE   *ImageType
  )
{
  EFI_STATUS            Status;
  EFI_HTTP_HEADER       *Header;
  CHAR8                 *FilePath;
  CHAR8                 *FilePost;

  if (Uri == NULL || UriParser == NULL || ImageType == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (HeaderCount != 0 && Headers == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Determine the image type by the HTTP Content-Type header field first.
  //   "application/efi"         -> EFI Image
  //   "application/vnd.efi-iso" -> CD/DVD Image
  //   "application/vnd.efi-img" -> Virtual Disk Image
  //
  Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_TYPE);
  if (Header != NULL) {
    if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_EFI) == 0) {
      *ImageType = ImageTypeEfi;
      return EFI_SUCCESS;
    } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_ISO) == 0) {
      *ImageType = ImageTypeVirtualCd;
      return EFI_SUCCESS;
    } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_IMG) == 0) {
      *ImageType = ImageTypeVirtualDisk;
      return EFI_SUCCESS;
    }
  }

  //
  // Determine the image type by file extension:
  //   *.efi -> EFI Image
  //   *.iso -> CD/DVD Image
  //   *.img -> Virtual Disk Image
  //
  Status = HttpUrlGetPath (
             Uri,
             UriParser,
             &FilePath
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FilePost = FilePath + AsciiStrLen (FilePath) - 4;
  if (AsciiStrCmp (FilePost, ".efi") == 0) {
    *ImageType = ImageTypeEfi;
  } else if (AsciiStrCmp (FilePost, ".iso") == 0) {
    *ImageType = ImageTypeVirtualCd;
  } else if (AsciiStrCmp (FilePost, ".img") == 0) {
    *ImageType = ImageTypeVirtualDisk;
  } else {
    *ImageType = ImageTypeMax;
  }

  FreePool (FilePath);

  return (*ImageType < ImageTypeMax) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
Beispiel #8
0
/**
  Perform a dir on a device. The device must support Simple File System Protocol
  or the FV protocol.

  Argv[0] - "dir"
  Argv[1] - Device Name:path. Path is optional
  Argv[2] - Optional filename to match on. A leading * means match substring
  Argv[3] - Optional FV file type

  dir fs1:\efi      ; perform a dir on fs1: device in the efi directory
  dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but
                      only print out files that contain the string *.efi
  dir fv1:\         ; perform a dir on fv1: device in the efi directory
                    NOTE: fv devices do not contain subdirs
  dir fv1:\ * PEIM  ; will match all files of type PEIM

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblDirCmd (
    IN UINTN  Argc,
    IN CHAR8  **Argv
)
{
    EFI_STATUS                    Status;
    EFI_OPEN_FILE                 *File;
    EFI_FILE_INFO                 *DirInfo;
    UINTN                         ReadSize;
    UINTN                         CurrentRow;
    CHAR16                        *MatchSubString;
    EFI_STATUS                    GetNextFileStatus;
    UINTN                         Key;
    EFI_FV_FILETYPE               SearchType;
    EFI_FV_FILETYPE               Type;
    EFI_FV_FILE_ATTRIBUTES        Attributes;
    UINTN                         Size;
    EFI_GUID                      NameGuid;
    EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
    UINT32                        AuthenticationStatus;
    VOID                          *Section;
    UINTN                         SectionSize;
    EFI_FV_FILETYPE               Index;
    UINTN                         Length;
    UINTN                         BestMatchCount;
    CHAR16                        UnicodeFileName[MAX_CMD_LINE];
    CHAR8                         *Path;
    CHAR8                         *TypeStr;
    UINTN                         TotalSize;


    if (Argc <= 1) {
        Path = EfiGetCwd ();
        if (Path == NULL) {
            return EFI_SUCCESS;
        }
    } else {
        Path = Argv[1];
    }

    File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
    if (File == NULL) {
        return EFI_SUCCESS;
    }

    if (File->Type == EfiOpenFirmwareVolume) {
        // FV Dir

        SearchType = EFI_FV_FILETYPE_ALL;
        UnicodeFileName[0] = '\0';
        MatchSubString = &UnicodeFileName[0];
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                // Handle *Name substring matching
                MatchSubString = &UnicodeFileName[1];
            }

            // Handle file type matchs
            if (Argc > 3) {
                // match a specific file type, always last argument
                Length = AsciiStrLen (Argv[3]);
                for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {
                    if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {
                        // exact match
                        SearchType = Index;
                        break;
                    }

                    if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {
                        // partial match, so keep looking to make sure there is only one partial match
                        BestMatchCount++;
                        SearchType = Index;
                    }
                }

                if (BestMatchCount > 1) {
                    SearchType = EFI_FV_FILETYPE_ALL;
                }
            }
        }

        TotalSize = 0;
        Fv = File->Fv;
        Key = 0;
        CurrentRow = 0;
        do {
            Type = SearchType;
            GetNextFileStatus = Fv->GetNextFile (
                                    Fv,
                                    &Key,
                                    &Type,
                                    &NameGuid,
                                    &Attributes,
                                    &Size
                                );
            if (!EFI_ERROR (GetNextFileStatus)) {
                TotalSize += Size;
                // Calculate size of entire file
                Section = NULL;
                Size = 0;
                Status = Fv->ReadFile (
                             Fv,
                             &NameGuid,
                             Section,
                             &Size,
                             &Type,
                             &Attributes,
                             &AuthenticationStatus
                         );
                if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {
                    // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid
                    Size = 0;
                }

                TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";

                // read the UI seciton to do a name match.
                Section = NULL;
                Status = Fv->ReadSection (
                             Fv,
                             &NameGuid,
                             EFI_SECTION_USER_INTERFACE,
                             0,
                             &Section,
                             &SectionSize,
                             &AuthenticationStatus
                         );
                if (!EFI_ERROR (Status)) {
                    if (StrStr (Section, MatchSubString) != NULL) {
                        AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                    FreePool (Section);
                } else {
                    if (*MatchSubString == '\0') {
                        AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                }
            }
        } while (!EFI_ERROR (GetNextFileStatus));

        if (SearchType == EFI_FV_FILETYPE_ALL) {
            AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);
        }


    } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {
        // Simple File System DIR

        if (File->FsFileInfo ==  NULL) {
            return EFI_SUCCESS;
        }

        if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
            return EFI_SUCCESS;
        }

        // Handle *Name substring matching
        MatchSubString = NULL;
        UnicodeFileName[0] = '\0';
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                MatchSubString = &UnicodeFileName[1];
            }
        }

        File->FsFileHandle->SetPosition (File->FsFileHandle, 0);
        for (CurrentRow = 0;;) {
            // First read gets the size
            DirInfo = NULL;
            ReadSize = 0;
            Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
            if (Status == EFI_BUFFER_TOO_SMALL) {
                // Allocate the buffer for the real read
                DirInfo = AllocatePool (ReadSize);
                if (DirInfo == NULL) {
                    goto Done;
                }

                // Read the data
                Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
                if ((EFI_ERROR (Status)) || (ReadSize == 0)) {
                    break;
                }
            } else {
                break;
            }

            if (MatchSubString != NULL) {
                if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {
                    // does not match *name argument, so skip
                    continue;
                }
            } else if (UnicodeFileName[0] != '\0') {
                // is not an exact match for name argument, so skip
                if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {
                    continue;
                }
            }

            if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {
                AsciiPrint ("         <DIR> %s\n", &DirInfo->FileName[0]);
            } else {
                AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);
            }

            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                break;
            }

            FreePool (DirInfo);
        }

Done:
        if (DirInfo != NULL) {
            FreePool (DirInfo);
        }
    }

    EfiClose (File);

    return EFI_SUCCESS;
}
Beispiel #9
0
/**
  Simple arm disassembler via a library

  Argv[0] - disasm
  Argv[1] - Address to start disassembling from
  ARgv[2] - Number of instructions to disassembly (optional)

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line. 
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblPerformance (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN       Key;
  CONST VOID  *Handle;
  CONST CHAR8 *Token, *Module;
  UINT64      Start, Stop, TimeStamp;
  UINT64      Delta, TicksPerSecond, Milliseconds, Microseconds;
  UINTN       Index;
  BOOLEAN     CountUp;

  TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);
  if (Start < Stop) {
    CountUp = TRUE;
  } else {
    CountUp = FALSE;
  }

  Key       = 0;
  do {
    Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
    if (Key != 0) {
      if (AsciiStriCmp ("StartImage:", Token) == 0) {
        if (Stop == 0) {
          // The entry for EBL is still running so the stop time will be zero. Skip it
          AsciiPrint ("   running     %a\n", ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
        } else {
          Delta =  CountUp?(Stop - Start):(Start - Stop);
          Microseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000000), TicksPerSecond, NULL);
          AsciiPrint ("%10ld us  %a\n", Microseconds, ImageHandleToPdbFileName ((EFI_HANDLE)Handle));
        }
      }
    }
  } while (Key != 0);

  AsciiPrint ("\n");

  TimeStamp = 0;
  Key       = 0;
  do {
    Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
    if (Key != 0) {
      for (Index = 0; mTokenList[Index] != NULL; Index++) {
        if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
          Delta =  CountUp?(Stop - Start):(Start - Stop);
          TimeStamp += Delta;
          Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
          AsciiPrint ("%6a %6ld ms\n", Token, Milliseconds);
          break;
        }
      }   
    }
  } while (Key != 0);

  AsciiPrint ("Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));

  return EFI_SUCCESS;
}
Beispiel #10
0
/**
  Parse the MTFTP6 extesion options.

  @param[in]  Options       The pointer to the extension options list.
  @param[in]  Count         The num of the extension options.
  @param[in]  IsRequest     If FALSE, the extension options is included
                            by a request packet.
  @param[in]  ExtInfo       The pointer to the option information to be filled.

  @retval EFI_SUCCESS            Parse the multicast option successfully.
  @retval EFI_INVALID_PARAMETER  There is one option is malformatted at least.
  @retval EFI_UNSUPPORTED        There is one option is not supported at least.

**/
EFI_STATUS
Mtftp6ParseExtensionOption (
  IN EFI_MTFTP6_OPTION        *Options,
  IN UINT32                   Count,
  IN BOOLEAN                  IsRequest,
  IN MTFTP6_EXT_OPTION_INFO   *ExtInfo
  )
{
  EFI_STATUS                  Status;
  EFI_MTFTP6_OPTION           *Opt;
  UINT32                      Index;
  UINT32                      Value;

  ExtInfo->BitMap = 0;

  for (Index = 0; Index < Count; Index++) {

    Opt = Options + Index;

    if (Opt->OptionStr == NULL || Opt->ValueStr == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "blksize") == 0) {
      //
      // block size option, valid value is between [8, 65464]
      //
      Value = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);

      if ((Value < 8) || (Value > 65464)) {
        return EFI_INVALID_PARAMETER;
      }

      ExtInfo->BlkSize = (UINT16) Value;
      ExtInfo->BitMap |= MTFTP6_OPT_BLKSIZE_BIT;

    } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "timeout") == 0) {
      //
      // timeout option, valid value is between [1, 255]
      //
      Value = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);

      if (Value < 1 || Value > 255) {
        return EFI_INVALID_PARAMETER;
      }

      ExtInfo->Timeout = (UINT8) Value;
      ExtInfo->BitMap |= MTFTP6_OPT_TIMEOUT_BIT;

    } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "tsize") == 0) {
      //
      // tsize option, the biggest transfer supported is 4GB with block size option
      //
      ExtInfo->Tsize   = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);
      ExtInfo->BitMap |= MTFTP6_OPT_TSIZE_BIT;

    } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "multicast") == 0) {
      //
      // Multicast option, if it is a request, the value must be a zero string,
      // otherwise, it must be like "addr,port,mc" string, mc indicates master.
      //
      if (!IsRequest) {

        Status = Mtftp6ParseMcastOption (Opt->ValueStr, ExtInfo);

        if (EFI_ERROR (Status)) {
          return Status;
        }
      } else if (*(Opt->ValueStr) != '\0') {

        return EFI_INVALID_PARAMETER;
      }

      ExtInfo->BitMap |= MTFTP6_OPT_MCAST_BIT;

    } else if (IsRequest) {
      //
      // If it's a request, unsupported; else if it's a reply, ignore.
      //
      return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}
Beispiel #11
0
/**
  Exit the EBL. If the command processor sees EFI_ABORTED return status it will
  exit the EBL.

  Argv[0] - "exit"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_ABORTED

**/
EFI_STATUS
EFIAPI
EblExitCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS              Status;
  UINTN                   MemoryMapSize;
  EFI_MEMORY_DESCRIPTOR   *MemoryMap;
  UINTN                   MapKey;
  UINTN                   DescriptorSize;
  UINT32                  DescriptorVersion;
  UINTN                   Pages;

  if (Argc > 1) {
    if (AsciiStriCmp (Argv[1], "efi") != 0) {
      return EFI_ABORTED;
    }
  } else if (Argc == 1) {
    return EFI_ABORTED;
  }

  MemoryMap = NULL;
  MemoryMapSize = 0;
  do {
    Status = gBS->GetMemoryMap (
                    &MemoryMapSize,
                    MemoryMap,
                    &MapKey,
                    &DescriptorSize,
                    &DescriptorVersion
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {

      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
      MemoryMap = AllocatePages (Pages);

      //
      // Get System MemoryMap
      //
      Status = gBS->GetMemoryMap (
                      &MemoryMapSize,
                      MemoryMap,
                      &MapKey,
                      &DescriptorSize,
                      &DescriptorVersion
                      );
      // Don't do anything between the GetMemoryMap() and ExitBootServices()
      if (!EFI_ERROR (Status)) {
        Status = gBS->ExitBootServices (gImageHandle, MapKey);
        if (EFI_ERROR (Status)) {
          FreePages (MemoryMap, Pages);
          MemoryMap = NULL;
          MemoryMapSize = 0;
        }
      }
    }
  } while (EFI_ERROR (Status));

  //
  // At this point it is very dangerous to do things EFI as most of EFI is now gone.
  // This command is useful if you are working with a debugger as it will shutdown
  // DMA and other things that could break a soft resets.
  //
  CpuDeadLoop ();

  // Should never get here, but makes the compiler happy
  return EFI_ABORTED;
}
/**
  Parse Config data file to get the updated data array.

  @param DataBuffer      Config raw file buffer.
  @param BufferSize      Size of raw buffer.
  @param NumOfUpdates    Pointer to the number of update data.
  @param UpdateArray     Pointer to the config of update data.

  @retval EFI_NOT_FOUND         No config data is found.
  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
  @retval EFI_SUCCESS           Parse the config file successfully.

**/
EFI_STATUS
ParseUpdateDataFile (
  IN      UINT8                         *DataBuffer,
  IN      UINTN                         BufferSize,
  IN OUT  UINTN                         *NumOfUpdates,
  IN OUT  UPDATE_CONFIG_DATA            **UpdateArray
  )
{
  EFI_STATUS                            Status;
  CHAR8                                 *Value;
  CHAR8                                 *SectionName;
  CHAR8                                 Entry[MAX_LINE_LENGTH];
  SECTION_ITEM                          *SectionHead;
  COMMENT_LINE                          *CommentHead;
  UINTN                                 Num;
  UINTN                                 Index;
  EFI_GUID                              FileGuid;

  SectionHead           = NULL;
  CommentHead           = NULL;

  //
  // First process the data buffer and get all sections and entries
  //
  Status                = PreProcessDataFile (
                            DataBuffer,
                            BufferSize,
                            &SectionHead,
                            &CommentHead
                            );
  if (EFI_ERROR (Status)) {
    FreeAllList (SectionHead, CommentHead);
    return Status;
  }

  //
  // Now get NumOfUpdate
  //
  Value                 = NULL;
  Status                = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) "Head",
                            (UINT8 *) "NumOfUpdate",
                            (UINT8 **) &Value
                            );
  if (Value == NULL) {
    FreeAllList (SectionHead, CommentHead);
    return EFI_NOT_FOUND;
  }
  Num                   = UpdateAtoi((UINT8 *) Value);
  if (Num <= 0) {
    FreeAllList (SectionHead, CommentHead);
    return EFI_NOT_FOUND;
  }

  *NumOfUpdates         = Num;
  *UpdateArray = AllocatePool ((sizeof (UPDATE_CONFIG_DATA) * Num));
  if (*UpdateArray == NULL) {
    FreeAllList (SectionHead, CommentHead);
    return EFI_OUT_OF_RESOURCES;
  }

  for ( Index = 0 ; Index < *NumOfUpdates ; Index++) {
    //
    // Get the section name of each update
    //
    AsciiStrCpyS (Entry, MAX_LINE_LENGTH, "Update");
    UpdateStrCatNumber ((UINT8 *) Entry, Index);
    Value               = NULL;
    Status              = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) "Head",
                            (UINT8 *) Entry,
                            (UINT8 **) &Value
                            );
    if (Value == NULL) {
      FreeAllList (SectionHead, CommentHead);
      return EFI_NOT_FOUND;
    }

    //
    // The section name of this update has been found.
    // Now looks for all the config data of this update
    //
    SectionName         = Value;

    //
    // UpdateType
    //
    Value               = NULL;
    Status              = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) SectionName,
                            (UINT8 *) "UpdateType",
                            (UINT8 **) &Value
                            );
    if (Value == NULL) {
      FreeAllList (SectionHead, CommentHead);
      return EFI_NOT_FOUND;
    }

    Num                 = UpdateAtoi((UINT8 *) Value);
    if (( Num >= (UINTN) UpdateOperationMaximum)) {
      FreeAllList (SectionHead, CommentHead);
      return Status;
    }
    (*UpdateArray)[Index].Index       = Index;
    (*UpdateArray)[Index].UpdateType  = (UPDATE_OPERATION_TYPE) Num;

    //
    // FvBaseAddress
    //
    Value               = NULL;
    Status              = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) SectionName,
                            (UINT8 *) "FvBaseAddress",
                            (UINT8 **) &Value
                            );
    if (Value == NULL) {
      FreeAllList (SectionHead, CommentHead);
      return EFI_NOT_FOUND;
    }

    Num                 = AsciiStrHexToUintn ((CONST CHAR8 *) Value);
    (*UpdateArray)[Index].BaseAddress = (EFI_PHYSICAL_ADDRESS) Num;

    //
    // FileBuid
    //
    Value               = NULL;
    Status              = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) SectionName,
                            (UINT8 *) "FileGuid",
                            (UINT8 **) &Value
                            );
    if (Value == NULL) {
      FreeAllList (SectionHead, CommentHead);
      return EFI_NOT_FOUND;
    }

    Status              = UpdateStringToGuid ((UINT8 *) Value, &FileGuid);
    if (EFI_ERROR (Status)) {
      FreeAllList (SectionHead, CommentHead);
      return Status;
    }
    CopyMem (&((*UpdateArray)[Index].FileGuid), &FileGuid, sizeof(EFI_GUID));

    //
    // FaultTolerant
    // Default value is FALSE
    //
    Value               = NULL;
    (*UpdateArray)[Index].FaultTolerant = FALSE;
    Status              = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) SectionName,
                            (UINT8 *) "FaultTolerant",
                            (UINT8 **) &Value
                           );
    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
      FreeAllList (SectionHead, CommentHead);
      return Status;
    } else if (Value != NULL) {
      if (AsciiStriCmp ((CONST CHAR8 *) Value, (CONST CHAR8 *) "TRUE") == 0) {
        (*UpdateArray)[Index].FaultTolerant = TRUE;
      } else if (AsciiStriCmp ((CONST CHAR8 *) Value, (CONST CHAR8 *) "FALSE") == 0) {
        (*UpdateArray)[Index].FaultTolerant = FALSE;
      }
    }

    if ((*UpdateArray)[Index].UpdateType == UpdateFvRange) {
      //
      // Length
      //
      Value             = NULL;
      Status            = UpdateGetProfileString (
                            SectionHead,
                            (UINT8 *) SectionName,
                            (UINT8 *) "Length",
                            (UINT8 **) &Value
                            );
      if (Value == NULL) {
        FreeAllList (SectionHead, CommentHead);
        return EFI_NOT_FOUND;
      }

      Num               = AsciiStrHexToUintn ((CONST CHAR8 *) Value);
      (*UpdateArray)[Index].Length = (UINTN) Num;
    }
  }

  //
  // Now all configuration data got. Free those temporary buffers
  //
  FreeAllList (SectionHead, CommentHead);

  return EFI_SUCCESS;
}