コード例 #1
0
ファイル: ScmiBaseProtocol.c プロジェクト: lersek/edk2
/** Common function which returns vendor details.

  @param[in] MessageId       SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR
                             OR
                             SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR

  @param[out] VendorIdentifier ASCII name of the vendor/subvendor.

  @retval EFI_SUCCESS       VendorIdentifier is returned.
  @retval EFI_DEVICE_ERROR  SCP returns an SCMI error.
  @retval !(EFI_SUCCESS)    Other errors.
**/
STATIC
EFI_STATUS
BaseDiscoverVendorDetails (
  IN  SCMI_MESSAGE_ID_BASE  MessageId,
  OUT UINT8                 VendorIdentifier[SCMI_MAX_STR_LEN]
  )
{
  EFI_STATUS    Status;
  UINT32        *ReturnValues;
  SCMI_COMMAND  Cmd;
  UINT32        PayloadLength;

  Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;
  Cmd.MessageId  = MessageId;

  PayloadLength = 0;

  Status = ScmiCommandExecute (
             &Cmd,
             &PayloadLength,
             &ReturnValues
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  AsciiStrCpyS (
    (CHAR8*)VendorIdentifier,
    SCMI_MAX_STR_LEN,
    (CONST CHAR8*)ReturnValues
    );

  return EFI_SUCCESS;
}
コード例 #2
0
ファイル: LinuxAtag.c プロジェクト: EvanLloyd/tianocore
STATIC
VOID
SetupCmdlineTag (
  IN CONST CHAR8 *CmdLine
  )
{
  UINT32 LineLength;

  // Increment the line length by 1 to account for the null string terminator character
  LineLength = AsciiStrLen (CmdLine) + 1;

  /* Check for NULL strings.
   * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.
   * Remember, you have at least one null string terminator character.
   */
  if (LineLength > 1) {
    mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof (LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;
    mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;

    /* place CommandLine into tag */
    AsciiStrCpyS (mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, LineLength, CmdLine);

    // move pointer to next tag
    mLinuxKernelCurrentAtag = next_tag_address (mLinuxKernelCurrentAtag);
  }
コード例 #3
0
ファイル: DxeCorePerformanceLib.c プロジェクト: andyvand/edk2
/**
  Dumps all the PEI performance log to DXE performance gauge array.

  This internal function dumps all the PEI performance log to the DXE performance gauge array.
  It retrieves the optional GUID HOB for PEI performance and then saves the performance data
  to DXE performance data structures.

**/
VOID
InternalGetPeiPerformance (
  VOID
  )
{
  EFI_HOB_GUID_TYPE                 *GuidHob;
  PEI_PERFORMANCE_LOG_HEADER        *LogHob;
  PEI_PERFORMANCE_LOG_ENTRY         *LogEntryArray;
  UINT32                            *LogIdArray;
  GAUGE_DATA_ENTRY_EX               *GaugeEntryExArray;
  UINT32                            Index;
  UINT32                            NumberOfEntries;

  NumberOfEntries = 0;
  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);

  //
  // Dump PEI Log Entries to DXE Guage Data structure.
  //
  GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid);
  if (GuidHob != NULL) {
    LogHob          = GET_GUID_HOB_DATA (GuidHob);
    LogEntryArray   = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1);

    NumberOfEntries = LogHob->NumberOfEntries;
    for (Index = 0; Index < NumberOfEntries; Index++) {
      GaugeEntryExArray[Index].Handle         = LogEntryArray[Index].Handle;
      AsciiStrCpyS (GaugeEntryExArray[Index].Token,  DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Token);
      AsciiStrCpyS (GaugeEntryExArray[Index].Module, DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Module);
      GaugeEntryExArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp;
      GaugeEntryExArray[Index].EndTimeStamp   = LogEntryArray[Index].EndTimeStamp;
      GaugeEntryExArray[Index].Identifier     = 0;
    }

    GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid);
    if (GuidHob != NULL) {
      LogIdArray    = GET_GUID_HOB_DATA (GuidHob);
      for (Index = 0; Index < NumberOfEntries; Index++) {
        GaugeEntryExArray[Index].Identifier   = LogIdArray[Index];
      }
    }
  }
  mGaugeData->NumberOfEntries = NumberOfEntries;
}
コード例 #4
0
ファイル: Performance.c プロジェクト: chinni1989/edk2
/**
  Get the name from the Driver handle, which can be a handle with
  EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.
  This name can be used in performance data logging.

  @param Handle          Driver handle.
  @param GaugeString     The output string to be logged by performance logger.

**/
VOID
GetNameFromHandle (
  IN  EFI_HANDLE     Handle,
  OUT CHAR8          *GaugeString
  )
{
  EFI_STATUS                  Status;
  EFI_LOADED_IMAGE_PROTOCOL   *Image;
  CHAR8                       *PdbFileName;
  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;

  AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");

  //
  // Get handle name from image protocol
  //
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &Image
                  );

  if (EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    Handle,
                    &gEfiDriverBindingProtocolGuid,
                    (VOID **) &DriverBinding,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return ;
    }
    //
    // Get handle name from image protocol
    //
    Status = gBS->HandleProtocol (
                    DriverBinding->ImageHandle,
                    &gEfiLoadedImageProtocolGuid,
                    (VOID **) &Image
                    );
  }

  PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);

  if (PdbFileName != NULL) {
    GetShortPdbFileName (PdbFileName, GaugeString);
  }

  return ;
}
コード例 #5
0
ファイル: Performance.c プロジェクト: chinni1989/edk2
/**
  Get the short verion of PDB file name to be
  used in performance data logging.

  @param PdbFileName     The long PDB file name.
  @param GaugeString     The output string to be logged by performance logger.

**/
VOID
GetShortPdbFileName (
  IN  CONST CHAR8  *PdbFileName,
  OUT       CHAR8  *GaugeString
  )
{
  UINTN Index;
  UINTN Index1;
  UINTN StartIndex;
  UINTN EndIndex;

  if (PdbFileName == NULL) {
    AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");
  } else {
    StartIndex = 0;
    for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
      ;

    for (Index = 0; PdbFileName[Index] != 0; Index++) {
      if (PdbFileName[Index] == '\\') {
        StartIndex = Index + 1;
      }

      if (PdbFileName[Index] == '.') {
        EndIndex = Index;
      }
    }

    Index1 = 0;
    for (Index = StartIndex; Index < EndIndex; Index++) {
      GaugeString[Index1] = PdbFileName[Index];
      Index1++;
      if (Index1 == PERF_TOKEN_LENGTH) {
        break;
      }
    }

    GaugeString[Index1] = 0;
  }

  return ;
}
コード例 #6
0
ファイル: PxeBcSupport.c プロジェクト: wensunshine/VisualUefi
/**
  Convert unsigned int number to decimal number.

  @param      Number         The unsigned int number will be converted.
  @param      Buffer         Pointer to the buffer to store the decimal number after transform.
  @param[in]  BufferSize     The maxsize of the buffer.
  
  @return the length of the number after transform.

**/
UINTN
UtoA10 (
  IN UINTN Number,
  IN CHAR8 *Buffer,
  IN UINTN BufferSize
  )
{
  UINTN Index;
  CHAR8 TempStr[64];

  Index           = 63;
  TempStr[Index]  = 0;

  do {
    Index--;
    TempStr[Index]  = (CHAR8) ('0' + (Number % 10));
    Number          = Number / 10;
  } while (Number != 0);

  AsciiStrCpyS (Buffer, BufferSize, &TempStr[Index]);

  return AsciiStrLen (Buffer);
}
コード例 #7
0
ファイル: Tcg2Smm.c プロジェクト: EvanLloyd/tianocore
/**
  Patch version string of Physical Presence interface supported by platform. The initial string tag in TPM 
ACPI table is "$PV".

  @param[in, out] Table          The TPM item in ACPI table.
  @param[in]      PPVer          Version string of Physical Presence interface supported by platform.

  @return                        The allocated address for the found region.

**/
EFI_STATUS
UpdatePPVersion (
  EFI_ACPI_DESCRIPTION_HEADER    *Table,
  CHAR8                          *PPVer
  )
{
  EFI_STATUS  Status;
  UINT8       *DataPtr;

  //
  // Patch some pointers for the ASL code before loading the SSDT.
  //
  for (DataPtr  = (UINT8 *)(Table + 1);
       DataPtr <= (UINT8 *) ((UINT8 *) Table + Table->Length - PHYSICAL_PRESENCE_VERSION_SIZE);
       DataPtr += 1) {
    if (AsciiStrCmp((CHAR8 *)DataPtr,  PHYSICAL_PRESENCE_VERSION_TAG) == 0) {
      Status = AsciiStrCpyS((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_SIZE, PPVer);
      DEBUG((EFI_D_INFO, "TPM2 Physical Presence Interface Version update status 0x%x\n", Status));
      return Status;
    }
  }

  return EFI_NOT_FOUND;
}
コード例 #8
0
ファイル: PeiPerformanceLib.c プロジェクト: kraxel/edk2
/**
  Convert PEI performance log to FPDT String boot record.

  @param  IsStart                 TRUE if the performance log is start log.
  @param  Handle                  Pointer to environment specific context used
                                  to identify the component being measured.
  @param  Token                   Pointer to a Null-terminated ASCII string
                                  that identifies the component being measured.
  @param  Module                  Pointer to a Null-terminated ASCII string
                                  that identifies the module being measured.
  @param  Ticker                  64-bit time stamp.
  @param  Identifier              32-bit identifier. If the value is 0, the created record
                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.

  @retval EFI_SUCCESS              Add FPDT boot record.
  @retval EFI_OUT_OF_RESOURCES     There are not enough resources to record the measurement.
  @retval EFI_UNSUPPORTED          No matched FPDT record.

**/
EFI_STATUS
InsertPeiFpdtMeasurement (
  IN BOOLEAN      IsStart,
  IN CONST VOID   *Handle,  OPTIONAL
  IN CONST CHAR8  *Token,   OPTIONAL
  IN CONST CHAR8  *Module,  OPTIONAL
  IN UINT64       Ticker,
  IN UINT32       Identifier
  )
{
  EFI_HOB_GUID_TYPE                     *GuidHob;
  UINTN                                 PeiPerformanceSize;
  UINT8                                 *PeiFirmwarePerformance;
  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
  FPDT_RECORD_PTR                       FpdtRecordPtr;
  FPDT_BASIC_RECORD_INFO                RecordInfo;
  CONST VOID                            *ModuleGuid;
  UINTN                                 DestMax;
  UINTN                                 StrLength;
  CONST CHAR8                           *StringPtr;
  EFI_STATUS                            Status;
  UINT16                                PeiPerformanceLogEntries;
  UINT64                                TimeStamp;

  StringPtr = NULL;
  FpdtRecordPtr.RecordHeader = NULL;
  PeiPerformanceLogHeader = NULL;

  //
  // Get record info (type, size, ProgressID and Module Guid).
  //
  Status = GetFpdtRecordInfo (IsStart, Handle, Token, Module, &RecordInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // If PERF_START()/PERF_END() have specified the ProgressID,it has high priority.
  // !!! Note: If the Perf is not the known Token used in the core but have same
  // ID with the core Token, this case will not be supported.
  // And in currtnt usage mode, for the unkown ID, there is a general rule:
  // If it is start pref: the lower 4 bits of the ID should be 0.
  // If it is end pref: the lower 4 bits of the ID should not be 0.
  // If input ID doesn't follow the rule, we will adjust it.
  //
  if ((Identifier != 0) && (IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
    return EFI_UNSUPPORTED;
  } else if ((Identifier != 0) && (!IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
    if (IsStart && ((Identifier & 0x000F) != 0)) {
      Identifier &= 0xFFF0;
    } else if ((!IsStart) && ((Identifier & 0x000F) == 0)) {
      Identifier += 1;
    }
    RecordInfo.ProgressID = (UINT16)Identifier;
  }

  //
  // Get the number of PeiPerformanceLogEntries form PCD.
  //
  PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
                                       PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
                                       PcdGet8 (PcdMaxPeiPerformanceLogEntries));

  //
  // Create GUID HOB Data.
  //
  GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
  PeiFirmwarePerformance = NULL;
  while (GuidHob != NULL) {
    //
    // PEI Performance HOB was found, then return the existing one.
    //
    PeiFirmwarePerformance  = (UINT8*)GET_GUID_HOB_DATA (GuidHob);
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize > PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
      PeiPerformanceLogHeader->HobIsFull = TRUE;
    }
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize <= PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + PeiPerformanceLogHeader->SizeOfAllEntries);
      break;
    }
    //
    // Previous HOB is used, then find next one.
    //
    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
  }

  if (GuidHob == NULL) {
    //
    // PEI Performance HOB was not found, then build one.
    //
    PeiPerformanceSize      = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
                              MAX_RECORD_SIZE * PeiPerformanceLogEntries;
    PeiFirmwarePerformance  = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
    if (PeiFirmwarePerformance != NULL) {
      ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
    }
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
  }

  if (PeiFirmwarePerformance == NULL) {
    //
    // there is no enough resource to store performance data
    //
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get the TimeStamp.
  //
  if (Ticker == 0) {
    Ticker    = GetPerformanceCounter ();
    TimeStamp = GetTimeInNanoSecond (Ticker);
  } else if (Ticker == 1) {
    TimeStamp = 0;
  } else {
    TimeStamp = GetTimeInNanoSecond (Ticker);
  }

  //
  // Get the ModuleGuid.
  //
  if (Handle != NULL) {
    ModuleGuid = Handle;
  } else {
    ModuleGuid = &gEfiCallerIdGuid;
  }

  switch (RecordInfo.Type) {
  case FPDT_GUID_EVENT_TYPE:
    FpdtRecordPtr.GuidEvent->Header.Type       = FPDT_GUID_EVENT_TYPE;
    FpdtRecordPtr.GuidEvent->Header.Length     = RecordInfo.RecordSize;;
    FpdtRecordPtr.GuidEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.GuidEvent->ProgressID        = RecordInfo.ProgressID;
    FpdtRecordPtr.GuidEvent->Timestamp         = TimeStamp;
    CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
    break;

  case FPDT_GUID_QWORD_EVENT_TYPE:
    FpdtRecordPtr.GuidQwordEvent->Header.Type     = FPDT_GUID_QWORD_EVENT_TYPE;
    FpdtRecordPtr.GuidQwordEvent->Header.Length   = RecordInfo.RecordSize;;
    FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.GuidQwordEvent->ProgressID      = RecordInfo.ProgressID;
    FpdtRecordPtr.GuidQwordEvent->Timestamp       = TimeStamp;
    PeiPerformanceLogHeader->LoadImageCount++;
    FpdtRecordPtr.GuidQwordEvent->Qword           = PeiPerformanceLogHeader->LoadImageCount;
    CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
    break;

  case FPDT_DYNAMIC_STRING_EVENT_TYPE:
    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordInfo.RecordSize;
    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.DynamicStringEvent->ProgressID        = RecordInfo.ProgressID;
    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
    CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;

    if (Token != NULL) {
      StringPtr                     = Token;
    } else if (Module != NULL) {
      StringPtr                     = Module;
    }
    if (StringPtr != NULL && AsciiStrLen (StringPtr) != 0) {
      DestMax                       = (RecordInfo.RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
      StrLength                     = AsciiStrLen (StringPtr);
      if (StrLength >= DestMax) {
        StrLength                   = DestMax -1;
      }
      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StrLength);
    } else {
      AsciiStrCpyS (FpdtRecordPtr.DynamicStringEvent->String, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, "unknown name");
    }
    break;

  default:
    //
    // Record is not supported in current PEI phase, return EFI_ABORTED
    //
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
コード例 #9
0
ファイル: Performance.c プロジェクト: chinni1989/edk2
/**

  Writes performance data of booting into the allocated memory.
  OS can process these records.

  @param  Event                 The triggered event.
  @param  Context               Context for this event.

**/
VOID
EFIAPI
WriteBootToOsPerformanceData (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS                Status;
  UINT32                    LimitCount;
  EFI_HANDLE                *Handles;
  UINTN                     NoHandles;
  CHAR8                     GaugeString[PERF_TOKEN_SIZE];
  UINT8                     *Ptr;
  UINT32                    Index;
  UINT64                    Ticker;
  UINT64                    Freq;
  UINT32                    Duration;
  UINTN                     LogEntryKey;
  CONST VOID                *Handle;
  CONST CHAR8               *Token;
  CONST CHAR8               *Module;
  UINT64                    StartTicker;
  UINT64                    EndTicker;
  UINT64                    StartValue;
  UINT64                    EndValue;
  BOOLEAN                   CountUp;
  UINTN                     EntryIndex;
  UINTN                     NumPerfEntries;
  //
  // List of flags indicating PerfEntry contains DXE handle
  //
  BOOLEAN                   *PerfEntriesAsDxeHandle;
  UINTN                     VarSize;

  //
  // Record the performance data for End of BDS
  //
  PERF_END(NULL, "BDS", NULL, 0);

  //
  // Retrieve time stamp count as early as possible
  //
  Ticker  = GetPerformanceCounter ();

  Freq    = GetPerformanceCounterProperties (&StartValue, &EndValue);
  
  Freq    = DivU64x32 (Freq, 1000);

  mPerfHeader.CpuFreq = Freq;

  //
  // Record BDS raw performance data
  //
  if (EndValue >= StartValue) {
    mPerfHeader.BDSRaw = Ticker - StartValue;
    CountUp            = TRUE;
  } else {
    mPerfHeader.BDSRaw = StartValue - Ticker;
    CountUp            = FALSE;
  }

  if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
    VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
    Status = gRT->GetVariable (
                    L"PerfDataMemAddr",
                    &gPerformanceProtocolGuid,
                    NULL,
                    &VarSize,
                    &mAcpiLowMemoryBase
                    );
    if (EFI_ERROR (Status)) {
      //
      // Fail to get the variable, return.
      //
      return;
    }
  }

  //
  // Put Detailed performance data into memory
  //
  Handles = NULL;
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &NoHandles,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  Ptr        = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
  LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);

  NumPerfEntries = 0;
  LogEntryKey    = 0;
  while ((LogEntryKey = GetPerformanceMeasurement (
                          LogEntryKey,
                          &Handle,
                          &Token,
                          &Module,
                          &StartTicker,
                          &EndTicker)) != 0) {
    NumPerfEntries++;
  }
  PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN));
  ASSERT (PerfEntriesAsDxeHandle != NULL);
  
  //
  // Get DXE drivers performance
  //
  for (Index = 0; Index < NoHandles; Index++) {
    Ticker = 0;
    LogEntryKey = 0;
    EntryIndex  = 0;
    while ((LogEntryKey = GetPerformanceMeasurement (
                            LogEntryKey,
                            &Handle,
                            &Token,
                            &Module,
                            &StartTicker,
                            &EndTicker)) != 0) {
      if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) {
        PerfEntriesAsDxeHandle[EntryIndex] = TRUE;
      }
      EntryIndex++;
      if ((Handle == Handles[Index]) && (EndTicker != 0)) {
        if (StartTicker == 1) {
          StartTicker = StartValue;
        }
        if (EndTicker == 1) {
          EndTicker = StartValue;
        }
        Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
      }
    }

    Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);

    if (Duration > 0) {

      GetNameFromHandle (Handles[Index], GaugeString);

      AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);
      mPerfData.Duration = Duration;

      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
      Ptr += sizeof (PERF_DATA);

      mPerfHeader.Count++;
      if (mPerfHeader.Count == LimitCount) {
        goto Done;
      }
    }
  }

  //
  // Get inserted performance data
  //
  LogEntryKey = 0;
  EntryIndex  = 0;
  while ((LogEntryKey = GetPerformanceMeasurement (
                          LogEntryKey,
                          &Handle,
                          &Token,
                          &Module,
                          &StartTicker,
                          &EndTicker)) != 0) {
    if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) {

      ZeroMem (&mPerfData, sizeof (PERF_DATA));

      AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);
      if (StartTicker == 1) {
        StartTicker = StartValue;
      }
      if (EndTicker == 1) {
        EndTicker = StartValue;
      }
      Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);

      mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);

      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
      Ptr += sizeof (PERF_DATA);

      mPerfHeader.Count++;
      if (mPerfHeader.Count == LimitCount) {
        goto Done;
      }
    }
    EntryIndex++;
  }

Done:

  FreePool (Handles);
  FreePool (PerfEntriesAsDxeHandle);

  mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;

  //
  // Put performance data to Reserved memory
  //
  CopyMem (
    (UINTN *) (UINTN) mAcpiLowMemoryBase,
    &mPerfHeader,
    sizeof (PERF_HEADER)
    );

  return ;
}
コード例 #10
0
ファイル: Main.c プロジェクト: EvanLloyd/tianocore
/**
  Embedded Boot Loader (EBL) - A simple EFI command line application for embedded
  devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that
  gets executed automatically. The ; separator allows multiple commands
  for each command line.

  @param  ImageHandle   EFI ImageHandle for this application.
  @param  SystemTable   EFI system table

  @return EFI status of the application

**/
EFI_STATUS
EFIAPI
EdkBootLoaderEntry (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS  Status;
  CHAR8       CmdLine[MAX_CMD_LINE];
  CHAR16      *CommandLineVariable = NULL;
  CHAR16      *CommandLineVariableName = L"default-cmdline";
  UINTN       CommandLineVariableSize = 0;
  EFI_GUID    VendorGuid;

  // Initialize tables of commands
  EblInitializeCmdTable ();
  EblInitializeDeviceCmd ();
  EblInitializemdHwDebugCmds ();
  EblInitializemdHwIoDebugCmds ();
  EblInitializeDirCmd ();
  EblInitializeHobCmd ();
  EblInitializeScriptCmd ();
  EblInitializeExternalCmd ();
  EblInitializeNetworkCmd();
  EblInitializeVariableCmds ();

  if (gST->ConOut == NULL) {
    DEBUG((EFI_D_ERROR,"Error: No Console Output\n"));
    return EFI_NOT_READY;
  }

  // Disable the 5 minute EFI watchdog time so we don't get automatically reset
  gBS->SetWatchdogTimer (0, 0, 0, NULL);

  if (FeaturePcdGet (PcdEmbeddedMacBoot)) {
    // A MAC will boot in graphics mode, so turn it back to text here
    // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.
    // DisableQuietBoot ();

    // Enable the biggest output screen size possible
    gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);

  }

  // Save current screen mode
  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows);

  EblPrintStartupBanner ();

  // Parse command line and handle commands separated by ;
  // The loop prints the prompt gets user input and saves history

  // Look for a variable with a default command line, otherwise use the Pcd
  ZeroMem(&VendorGuid, sizeof(EFI_GUID));

  Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    CommandLineVariable = AllocatePool(CommandLineVariableSize);

    Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);
    if (!EFI_ERROR(Status)) {
      UnicodeStrToAsciiStrS (CommandLineVariable, CmdLine, MAX_CMD_LINE);
    }

    FreePool(CommandLineVariable);
  }

  if (EFI_ERROR(Status)) {
    AsciiStrCpyS (CmdLine, MAX_CMD_LINE, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand));
  }

  for (;;) {
    Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE);
    if (Status == EFI_ABORTED) {
      // if a command returns EFI_ABORTED then exit the EBL
      EblShutdownExternalCmdTable ();
      return EFI_SUCCESS;
    }

    // get the command line from the user
    EblPrompt ();
    GetCmd (CmdLine, MAX_CMD_LINE);
    SetCmdHistory (CmdLine);

    if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) {
      // Probe removable media devices to see if media has been inserted or removed.
      EblProbeRemovableMedia ();
    }
  }
}
コード例 #11
0
ファイル: IScsiDhcp.c プロジェクト: EvanLloyd/tianocore
/**
  Extract the Root Path option and get the required target information.

  @param[in]        RootPath         The RootPath.
  @param[in]        Length           Length of the RootPath option payload.
  @param[in, out]   ConfigData       The iSCSI attempt configuration data read
                                     from a nonvolatile device.

  @retval EFI_SUCCESS           All required information is extracted from the RootPath option.
  @retval EFI_NOT_FOUND         The RootPath is not an iSCSI RootPath.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
  @retval EFI_INVALID_PARAMETER The RootPath is malformatted.

**/
EFI_STATUS
IScsiDhcpExtractRootPath (
  IN      CHAR8                        *RootPath,
  IN      UINT8                        Length,
  IN OUT  ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
  )
{
  EFI_STATUS                  Status;
  UINT8                       IScsiRootPathIdLen;
  CHAR8                       *TmpStr;
  ISCSI_ROOT_PATH_FIELD       Fields[RP_FIELD_IDX_MAX];
  ISCSI_ROOT_PATH_FIELD       *Field;
  UINT32                      FieldIndex;
  UINT8                       Index;
  ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
  EFI_IP_ADDRESS              Ip;
  UINT8                       IpMode;

  ConfigNvData = &ConfigData->SessionConfigData;

  //
  // "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
  //
  IScsiRootPathIdLen = (UINT8) AsciiStrLen (ISCSI_ROOT_PATH_ID);

  if ((Length <= IScsiRootPathIdLen) || (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
    return EFI_NOT_FOUND;
  }
  //
  // Skip the iSCSI RootPath ID "iscsi:".
  //
  RootPath += IScsiRootPathIdLen;
  Length  = (UINT8) (Length - IScsiRootPathIdLen);

  TmpStr  = (CHAR8 *) AllocatePool (Length + 1);
  if (TmpStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (TmpStr, RootPath, Length);
  TmpStr[Length]  = '\0';

  Index           = 0;
  FieldIndex      = RP_FIELD_IDX_SERVERNAME;
  ZeroMem (&Fields[0], sizeof (Fields));

  //
  // Extract the fields in the Root Path option string.
  //
  for (FieldIndex = RP_FIELD_IDX_SERVERNAME; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {
    if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
      Fields[FieldIndex].Str = &TmpStr[Index];
    }

    while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
      Index++;
    }

    if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
      if (FieldIndex != RP_FIELD_IDX_TARGETNAME) {
        TmpStr[Index] = '\0';
        Index++;
      }

      if (Fields[FieldIndex].Str != NULL) {
        Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
      }
    }
  }

  if (FieldIndex != RP_FIELD_IDX_MAX) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
      (Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||
      (Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)
      ) {

    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Get the IP address of the target.
  //
  Field   = &Fields[RP_FIELD_IDX_SERVERNAME];

  if (ConfigNvData->IpMode < IP_MODE_AUTOCONFIG) {
    IpMode = ConfigNvData->IpMode;
  } else {
    IpMode = ConfigData->AutoConfigureMode;
  }

  Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
  CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  //
  // Check the protocol type.
  //
  Field = &Fields[RP_FIELD_IDX_PROTOCOL];
  if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Get the port of the iSCSI target.
  //
  Field = &Fields[RP_FIELD_IDX_PORT];
  if (Field->Str != NULL) {
    ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
  } else {
    ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
  }
  //
  // Get the LUN.
  //
  Field = &Fields[RP_FIELD_IDX_LUN];
  if (Field->Str != NULL) {
    Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  } else {
    ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
  }
  //
  // Get the target iSCSI Name.
  //
  Field = &Fields[RP_FIELD_IDX_TARGETNAME];

  if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Validate the iSCSI name.
  //
  Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  AsciiStrCpyS (ConfigNvData->TargetName, ISCSI_NAME_MAX_SIZE, Field->Str);

ON_EXIT:

  FreePool (TmpStr);

  return Status;
}
コード例 #12
0
/**
  Used to allocate and build a device path node for a SCSI device on a SCSI channel.

  @param[in]      This        A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param[in]      Target      The Target is an array of size TARGET_MAX_BYTES and it specifies the
                              Target ID of the SCSI device for which a device path node is to be
                              allocated and built. Transport drivers may chose to utilize a subset of
                              this size to suit the representation of targets. For example, a Fibre
                              Channel driver may use only 8 bytes (WWN) in the array to represent a
                              FC target.
  @param[in]       Lun        The LUN of the SCSI device for which a device path node is to be
                              allocated and built.
  @param[in, out]  DevicePath A pointer to a single device path node that describes the SCSI device
                              specified by Target and Lun. This function is responsible for
                              allocating the buffer DevicePath with the boot service
                              AllocatePool(). It is the caller's responsibility to free
                              DevicePath when the caller is finished with DevicePath.

  @retval EFI_SUCCESS           The device path node that describes the SCSI device specified by
                                Target and Lun was allocated and returned in
                                DevicePath.
  @retval EFI_INVALID_PARAMETER DevicePath is NULL.
  @retval EFI_NOT_FOUND         The SCSI devices specified by Target and Lun does not exist
                                on the SCSI channel.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to allocate DevicePath.

**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruBuildDevicePath (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun,
  IN OUT EFI_DEVICE_PATH_PROTOCOL     **DevicePath
  )
{
  ISCSI_DRIVER_DATA             *Private;
  ISCSI_SESSION                 *Session;
  ISCSI_SESSION_CONFIG_NVDATA   *ConfigNvData;
  ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
  EFI_DEV_PATH                  *Node;
  UINTN                         DevPathNodeLen;

  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Target[0] != 0) {
    return EFI_NOT_FOUND;
  }

  Private       = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
  Session       = &Private->Session;
  ConfigNvData  = &Session->ConfigData.NvData;
  AuthConfig    = &Session->AuthData.AuthConfig;

  if (CompareMem (&Lun, ConfigNvData->BootLun, sizeof (UINT64)) != 0) {
    return EFI_NOT_FOUND;
  }

  DevPathNodeLen  = sizeof (ISCSI_DEVICE_PATH) + AsciiStrLen (ConfigNvData->TargetName) + 1;
  Node            = AllocatePool (DevPathNodeLen);
  if (Node == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
  Node->DevPath.SubType = MSG_ISCSI_DP;
  SetDevicePathNodeLength (&Node->DevPath, (UINT16)DevPathNodeLen);

  //
  // 0 for TCP, others are reserved.
  //
  Node->Iscsi.NetworkProtocol = 0;

  Node->Iscsi.LoginOption     = 0;
  switch (AuthConfig->CHAPType) {
  case ISCSI_CHAP_NONE:
    Node->Iscsi.LoginOption |= 0x0800;
    break;

  case ISCSI_CHAP_UNI:
    Node->Iscsi.LoginOption |= 0x1000;
    break;

  default:
    break;
  }

  CopyMem (&Node->Iscsi.Lun, ConfigNvData->BootLun, sizeof (UINT64));
  Node->Iscsi.TargetPortalGroupTag = Session->TargetPortalGroupTag;
  AsciiStrCpyS ((CHAR8 *) Node + sizeof (ISCSI_DEVICE_PATH), AsciiStrLen (ConfigNvData->TargetName) + 1, ConfigNvData->TargetName);

  *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;

  return EFI_SUCCESS;
}
コード例 #13
0
ファイル: SmbiosDxe.c プロジェクト: MattDevo/edk2
/**
  Update the string associated with an existing SMBIOS record.

  @param  This                  The EFI_SMBIOS_PROTOCOL instance.
  @param  SmbiosHandle          SMBIOS Handle of structure that will have its string updated.
  @param  StringNumber          The non-zero string number of the string to update
  @param  String                Update the StringNumber string with String.

  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.
  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist.
  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.
  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.

**/
EFI_STATUS
EFIAPI
SmbiosUpdateString (
  IN CONST EFI_SMBIOS_PROTOCOL      *This,
  IN EFI_SMBIOS_HANDLE              *SmbiosHandle,
  IN UINTN                          *StringNumber,
  IN CHAR8                          *String
  )
{
  UINTN                     InputStrLen;
  UINTN                     TargetStrLen;
  UINTN                     StrIndex;
  UINTN                     TargetStrOffset;
  UINTN                     NewEntrySize;
  CHAR8                     *StrStart;
  VOID                      *Raw;
  LIST_ENTRY                *Link;
  LIST_ENTRY                *Head;
  EFI_STATUS                Status;
  SMBIOS_INSTANCE           *Private;
  EFI_SMBIOS_ENTRY          *SmbiosEntry;
  EFI_SMBIOS_ENTRY          *ResizedSmbiosEntry;
  EFI_SMBIOS_HANDLE         MaxSmbiosHandle;
  EFI_SMBIOS_TABLE_HEADER   *Record;
  EFI_SMBIOS_RECORD_HEADER  *InternalRecord;

  //
  // Check args validity
  //
  GetMaxSmbiosHandle(This, &MaxSmbiosHandle);

  if (*SmbiosHandle > MaxSmbiosHandle) {
    return EFI_INVALID_PARAMETER;
  }

  if (String == NULL) {
    return EFI_ABORTED;
  }

  if (*StringNumber == 0) {
    return EFI_NOT_FOUND;
  }

  InputStrLen = AsciiStrLen(String);

  if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {
    if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {
      return EFI_UNSUPPORTED;
    }
  } else if (This->MajorVersion < 3) {
    //
    // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.
    // However, the length of the entire structure table (including all strings) must be reported
    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
    // which is a WORD field limited to 65,535 bytes.
    //
    if (InputStrLen > SMBIOS_TABLE_MAX_LENGTH) {
      return EFI_UNSUPPORTED;
    }
  } else {
    if (InputStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH) {
      //
      // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.
      // The input string length should not exceed 0xFFFFFFFF bytes.
      //
      return EFI_UNSUPPORTED;
    }
  }

  Private = SMBIOS_INSTANCE_FROM_THIS (This);
  //
  // Enter into critical section
  //
  Status = EfiAcquireLockOrFail (&Private->DataLock);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Head = &Private->DataListHead;
  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);
    Record = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);

    if (Record->Handle == *SmbiosHandle) {
      //
      // Find out the specified SMBIOS record
      //
      if (*StringNumber > SmbiosEntry->RecordHeader->NumberOfStrings) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_NOT_FOUND;
      }
      //
      // Point to unformed string section
      //
      StrStart = (CHAR8 *) Record + Record->Length;

      for (StrIndex = 1, TargetStrOffset = 0; StrIndex < *StringNumber; StrStart++, TargetStrOffset++) {
        //
        // A string ends in 00h
        //
        if (*StrStart == 0) {
          StrIndex++;
        }

        //
        // String section ends in double-null (0000h)
        //
        if (*StrStart == 0 && *(StrStart + 1) == 0) {
          EfiReleaseLock (&Private->DataLock);
          return EFI_NOT_FOUND;
        }
      }

      if (*StrStart == 0) {
        StrStart++;
        TargetStrOffset++;
      }

      //
      // Now we get the string target
      //
      TargetStrLen = AsciiStrLen(StrStart);
      if (InputStrLen == TargetStrLen) {
        AsciiStrCpyS(StrStart, TargetStrLen + 1, String);
        //
        // Some UEFI drivers (such as network) need some information in SMBIOS table.
        // Here we create SMBIOS table and publish it in
        // configuration table, so other UEFI drivers can get SMBIOS table from
        // configuration table without depending on PI SMBIOS protocol.
        //
        SmbiosTableConstruction (SmbiosEntry->Smbios32BitTable, SmbiosEntry->Smbios64BitTable);
        EfiReleaseLock (&Private->DataLock);
        return EFI_SUCCESS;
      }

      SmbiosEntry->Smbios32BitTable = FALSE;
      SmbiosEntry->Smbios64BitTable = FALSE;
      if ((This->MajorVersion < 0x3) ||
          ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {
        //
        // 32-bit table is produced, check the valid length.
        //
        if ((EntryPointStructure != NULL) &&
            (EntryPointStructure->TableLength + InputStrLen - TargetStrLen > SMBIOS_TABLE_MAX_LENGTH)) {
          //
          // The length of the entire structure table (including all strings) must be reported
          // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
          // which is a WORD field limited to 65,535 bytes.
          //
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 32-bit table length\n"));
        } else {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 32-bit table\n"));
          SmbiosEntry->Smbios32BitTable = TRUE;
        }
      }

      if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {
        //
        // 64-bit table is produced, check the valid length.
        //
        if ((Smbios30EntryPointStructure != NULL) &&
            (Smbios30EntryPointStructure->TableMaximumSize + InputStrLen - TargetStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH)) {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 64-bit table length\n"));
        } else {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 64-bit table\n"));
          SmbiosEntry->Smbios64BitTable = TRUE;
        }
      }

      if ((!SmbiosEntry->Smbios32BitTable) && (!SmbiosEntry->Smbios64BitTable)) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_UNSUPPORTED;
      }

      //
      // Original string buffer size is not exactly match input string length.
      // Re-allocate buffer is needed.
      //
      NewEntrySize = SmbiosEntry->RecordSize + InputStrLen - TargetStrLen;
      ResizedSmbiosEntry = AllocateZeroPool (NewEntrySize);

      if (ResizedSmbiosEntry == NULL) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_OUT_OF_RESOURCES;
      }

      InternalRecord  = (EFI_SMBIOS_RECORD_HEADER *) (ResizedSmbiosEntry + 1);
      Raw     = (VOID *) (InternalRecord + 1);

      //
      // Build internal record Header
      //
      InternalRecord->Version     = EFI_SMBIOS_RECORD_HEADER_VERSION;
      InternalRecord->HeaderSize  = (UINT16) sizeof (EFI_SMBIOS_RECORD_HEADER);
      InternalRecord->RecordSize  = SmbiosEntry->RecordHeader->RecordSize + InputStrLen - TargetStrLen;
      InternalRecord->ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;
      InternalRecord->NumberOfStrings = SmbiosEntry->RecordHeader->NumberOfStrings;

      //
      // Copy SMBIOS structure and optional strings.
      //
      CopyMem (Raw, SmbiosEntry->RecordHeader + 1, Record->Length + TargetStrOffset);
      CopyMem ((VOID*)((UINTN)Raw + Record->Length + TargetStrOffset), String, InputStrLen + 1);
      CopyMem ((CHAR8*)((UINTN)Raw + Record->Length + TargetStrOffset + InputStrLen + 1),
               (CHAR8*)Record + Record->Length + TargetStrOffset + TargetStrLen + 1,
               SmbiosEntry->RecordHeader->RecordSize - sizeof (EFI_SMBIOS_RECORD_HEADER) - Record->Length - TargetStrOffset - TargetStrLen - 1);

      //
      // Insert new record
      //
      ResizedSmbiosEntry->Signature    = EFI_SMBIOS_ENTRY_SIGNATURE;
      ResizedSmbiosEntry->RecordHeader = InternalRecord;
      ResizedSmbiosEntry->RecordSize   = NewEntrySize;
      ResizedSmbiosEntry->Smbios32BitTable = SmbiosEntry->Smbios32BitTable;
      ResizedSmbiosEntry->Smbios64BitTable = SmbiosEntry->Smbios64BitTable;
      InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link);

      //
      // Remove old record
      //
      RemoveEntryList(Link);
      FreePool(SmbiosEntry);
      //
      // Some UEFI drivers (such as network) need some information in SMBIOS table.
      // Here we create SMBIOS table and publish it in
      // configuration table, so other UEFI drivers can get SMBIOS table from
      // configuration table without depending on PI SMBIOS protocol.
      //
      SmbiosTableConstruction (ResizedSmbiosEntry->Smbios32BitTable, ResizedSmbiosEntry->Smbios64BitTable);
      EfiReleaseLock (&Private->DataLock);
      return EFI_SUCCESS;
    }
  }

  EfiReleaseLock (&Private->DataLock);
  return EFI_INVALID_PARAMETER;
}
コード例 #14
0
ファイル: DebugLib.c プロジェクト: wensunshine/VisualUefi
/**
  Prints a debug message to the debug output device if the specified error level is enabled.

  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 
  GetDebugPrintErrorLevel (), then print the message specified by Format and the 
  associated variable argument list to the debug output device.

  If Format is NULL, then ASSERT().

  If the length of the message string specificed by Format is larger than the maximum allowable
  record length, then directly return and not print it.

  @param  ErrorLevel  The error level of the debug message.
  @param  Format      Format string for the debug message to print.
  @param  ...         Variable argument list whose contents are accessed 
                      based on the format string specified by Format.

**/
VOID
EFIAPI
DebugPrint (
  IN  UINTN        ErrorLevel,
  IN  CONST CHAR8  *Format,
  ...
  )
{
  UINT64          Buffer[(EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)) + 1];
  EFI_DEBUG_INFO  *DebugInfo;
  UINTN           TotalSize;
  UINTN           DestBufferSize;
  VA_LIST         VaListMarker;
  BASE_LIST       BaseListMarker;
  CHAR8           *FormatString;
  BOOLEAN         Long;

  //
  // If Format is NULL, then ASSERT().
  //
  ASSERT (Format != NULL);

  //
  // Check driver Debug Level value and global debug level
  //
  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
    return;
  }

  //
  // Compute the total size of the record.
  // Note that the passing-in format string and variable parameters will be constructed to 
  // the following layout:
  //
  //         Buffer->|------------------------|
  //                 |         Padding        | 4 bytes
  //      DebugInfo->|------------------------|
  //                 |      EFI_DEBUG_INFO    | sizeof(EFI_DEBUG_INFO)
  // BaseListMarker->|------------------------|
  //                 |           ...          |
  //                 |   variable arguments   | 12 * sizeof (UINT64)
  //                 |           ...          |
  //                 |------------------------|
  //                 |       Format String    |
  //                 |------------------------|<- (UINT8 *)Buffer + sizeof(Buffer)
  //
  TotalSize = 4 + sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrSize (Format);

  //
  // If the TotalSize is larger than the maximum record size, then return
  //
  if (TotalSize > sizeof (Buffer)) {
    return;
  }

  //
  // Fill in EFI_DEBUG_INFO
  //
  // Here we skip the first 4 bytes of Buffer, because we must ensure BaseListMarker is
  // 64-bit aligned, otherwise retrieving 64-bit parameter from BaseListMarker will cause
  // exception on IPF. Buffer starts at 64-bit aligned address, so skipping 4 types (sizeof(EFI_DEBUG_INFO))
  // just makes address of BaseListMarker, which follows DebugInfo, 64-bit aligned.
  //
  DebugInfo             = (EFI_DEBUG_INFO *)(Buffer) + 1;
  DebugInfo->ErrorLevel = (UINT32)ErrorLevel;
  BaseListMarker        = (BASE_LIST)(DebugInfo + 1);
  FormatString          = (CHAR8 *)((UINT64 *)(DebugInfo + 1) + 12);

  //
  // Copy the Format string into the record
  //
  // According to the content structure of Buffer shown above, the size of
  // the FormatString buffer is the size of Buffer minus the Padding
  // (4 bytes), minus the size of EFI_DEBUG_INFO, minus the size of
  // variable arguments (12 * sizeof (UINT64)).
  //
  DestBufferSize = sizeof (Buffer) - 4 - sizeof (EFI_DEBUG_INFO) - 12 * sizeof (UINT64);
  AsciiStrCpyS (FormatString, DestBufferSize / sizeof (CHAR8), Format);

  //
  // The first 12 * sizeof (UINT64) bytes following EFI_DEBUG_INFO are for variable arguments
  // of format in DEBUG string, which is followed by the DEBUG format string.
  // Here we will process the variable arguments and pack them in this area.
  //
  VA_START (VaListMarker, Format);
  for (; *Format != '\0'; Format++) {
    //
    // Only format with prefix % is processed.
    //
    if (*Format != '%') {
      continue;
    }
    Long = FALSE;
    //
    // Parse Flags and Width
    //
    for (Format++; TRUE; Format++) {
      if (*Format == '.' || *Format == '-' || *Format == '+' || *Format == ' ') {
        //
        // These characters in format field are omitted.
        //
        continue;
      }
      if (*Format >= '0' && *Format <= '9') {
        //
        // These characters in format field are omitted.
        //
        continue;
      }
      if (*Format == 'L' || *Format == 'l') {
        //
        // 'L" or "l" in format field means the number being printed is a UINT64
        //
        Long = TRUE;
        continue;
      }
      if (*Format == '*') {
        //
        // '*' in format field means the precision of the field is specified by
        // a UINTN argument in the argument list.
        //
        BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);
        continue;
      }
      if (*Format == '\0') {
        //
        // Make no output if Format string terminates unexpectedly when
        // looking up for flag, width, precision and type. 
        //
        Format--;
      }
      //
      // When valid argument type detected or format string terminates unexpectedly,
      // the inner loop is done.
      //
      break;
    }
    
    //
    // Pack variable arguments into the storage area following EFI_DEBUG_INFO.
    //
    if ((*Format == 'p') && (sizeof (VOID *) > 4)) {
      Long = TRUE;
    }
    if (*Format == 'p' || *Format == 'X' || *Format == 'x' || *Format == 'd' || *Format == 'u') {
      if (Long) {
        BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);
      } else {
        BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);
      }
    } else if (*Format == 's' || *Format == 'S' || *Format == 'a' || *Format == 'g' || *Format == 't') {
      BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);
    } else if (*Format == 'c') {
コード例 #15
0
/**
  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;
}
コード例 #16
0
ファイル: DxeCorePerformanceLib.c プロジェクト: andyvand/edk2
/**
  Adds a record at the end of the performance measurement log
  that records the start time of a performance measurement.

  Adds a record to the end of the performance measurement log
  that contains the Handle, Token, Module and Identifier.
  The end time of the new record must be set to zero.
  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
  If TimeStamp is zero, the start time in the record is filled in with the value
  read from the current time stamp.

  @param  Handle                  Pointer to environment specific context used
                                  to identify the component being measured.
  @param  Token                   Pointer to a Null-terminated ASCII string
                                  that identifies the component being measured.
  @param  Module                  Pointer to a Null-terminated ASCII string
                                  that identifies the module being measured.
  @param  TimeStamp               64-bit time stamp.
  @param  Identifier              32-bit identifier. If the value is 0, the created record
                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.

  @retval EFI_SUCCESS             The data was read correctly from the device.
  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.

**/
EFI_STATUS
EFIAPI
StartGaugeEx (
  IN CONST VOID   *Handle,  OPTIONAL
  IN CONST CHAR8  *Token,   OPTIONAL
  IN CONST CHAR8  *Module,  OPTIONAL
  IN UINT64       TimeStamp,
  IN UINT32       Identifier
  )
{
  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;
  UINTN                     GaugeDataSize;
  GAUGE_DATA_HEADER         *NewGaugeData;
  UINTN                     OldGaugeDataSize;
  GAUGE_DATA_HEADER         *OldGaugeData;
  UINT32                    Index;

  Index = mGaugeData->NumberOfEntries;
  if (Index >= mMaxGaugeRecords) {
    //
    // Try to enlarge the scale of gauge array.
    //
    OldGaugeData      = mGaugeData;
    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;

    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords * 2;

    NewGaugeData = AllocateZeroPool (GaugeDataSize);
    if (NewGaugeData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    mGaugeData = NewGaugeData;
    mMaxGaugeRecords *= 2;

    //
    // Initialize new data array and migrate old data one.
    //
    mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);

    FreePool (OldGaugeData);
  }

  GaugeEntryExArray               = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);
  GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;

  if (Token != NULL) {
    AsciiStrCpyS (GaugeEntryExArray[Index].Token, DXE_PERFORMANCE_STRING_SIZE, Token);
  }
  if (Module != NULL) {
    AsciiStrCpyS (GaugeEntryExArray[Index].Module, DXE_PERFORMANCE_STRING_SIZE, Module);
  }

  GaugeEntryExArray[Index].EndTimeStamp = 0;
  GaugeEntryExArray[Index].Identifier = Identifier;

  if (TimeStamp == 0) {
    TimeStamp = GetPerformanceCounter ();
  }
  GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;

  mGaugeData->NumberOfEntries++;

  return EFI_SUCCESS;
}
コード例 #17
0
ファイル: Command.c プロジェクト: EvanLloyd/tianocore
EFI_STATUS
OutputData (
  IN UINT8  *Address,
  IN UINTN  Length,
  IN UINTN  Width,
  IN UINTN  Offset
  )
{
  UINT8 *EndAddress;
  UINTN Line;
  CHAR8 TextLine[0x11];
  UINTN CurrentRow = 0;
  UINTN Bytes;
  UINTN Spaces   = 0;
  CHAR8 Blanks[80];

  AsciiStrCpyS (Blanks, sizeof Blanks, mBlanks);
  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line) {
    AsciiPrint ("%08x: ", Offset);
    for (Line = 0; (Line < 0x10) && (Address < EndAddress);) {
      Bytes = EndAddress - Address;

      switch (Width) {
        case 4:
          if (Bytes >= 4) {
            AsciiPrint ("%08x ", *((UINT32 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%08x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 2:
          if (Bytes >= 2) {
            AsciiPrint ("%04x ", *((UINT16 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%04x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 1:
          AsciiPrint ("%02x ", *((UINT8 *)Address));
          TextLine[Line++] = ConvertToTextLine(*Address++);
          break;

        default:
          AsciiPrint ("Width must be 1, 2, or 4!\n");
          return EFI_INVALID_PARAMETER;
      }
    }

    // Pad spaces
    if (Line < 0x10) {
      switch (Width) {
        case 4:
          Spaces = 9 * ((0x10 - Line)/4);
          break;
        case 2:
          Spaces = 5 * ((0x10 - Line)/2);
          break;
        case 1:
          Spaces = 3 * (0x10 - Line);
          break;
      }

      Blanks[Spaces] = '\0';

      AsciiPrint(Blanks);

      Blanks[Spaces] = ' ';
    }

    TextLine[Line] = 0;
    AsciiPrint ("|%a|\n", TextLine);

    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
      return EFI_END_OF_FILE;
    }
  }

  if (Length % Width != 0) {
    AsciiPrint ("%08x\n", Offset);
  }

  return EFI_SUCCESS;
}