Exemplo n.º 1
0
/**

  Prints an assert message containing a filename, line number, and description.  
  This may be followed by a breakpoint or a dead loop.

  Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n" 
  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 
  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 
  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 
  CpuDeadLoop() is called.  If neither of these bits are set, then this function 
  returns immediately after the message is printed to the debug output device.
  DebugAssert() must actively prevent recusrsion.  If DebugAssert() is called while
  processing another DebugAssert(), then DebugAssert() must return immediately.

  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.

  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.

  @param  FileName     Pointer to the name of the source file that generated the assert condition.
  @param  LineNumber   The line number in the source file that generated the assert condition
  @param  Description  Pointer to the description of the assert condition.

**/
VOID
EFIAPI
DebugAssert (
  IN CONST CHAR8  *FileName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *Description
  )
{
  UINT64                 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)];
  EFI_DEBUG_ASSERT_DATA  *AssertData;
  UINTN                  TotalSize;
  CHAR8                  *Temp;
  UINTN                  FileNameLength;
  UINTN                  DescriptionLength;

  //
  // Make sure it will all fit in the passed in buffer
  //
  FileNameLength    = AsciiStrLen (FileName);
  DescriptionLength = AsciiStrLen (Description);
  TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + FileNameLength + 1 + DescriptionLength + 1;
  if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) {
    //
    // Fill in EFI_DEBUG_ASSERT_DATA
    //
    AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer;
    AssertData->LineNumber = (UINT32)LineNumber;

    //
    // Copy Ascii FileName including NULL.
    //
    Temp = AsciiStrCpy ((CHAR8 *)(AssertData + 1), FileName);

    //
    // Copy Ascii Description 
    //
    AsciiStrCpy (Temp + AsciiStrLen (FileName) + 1, Description);

    REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
      (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),
      AssertData,
      TotalSize
      );
  }

  //
  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
  //
  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
    CpuBreakpoint ();
  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
    CpuDeadLoop ();
  }
}
Exemplo n.º 2
0
EFI_STATUS
FileDelete (
  IN EFI_FILE *File
  )
{
  SEMIHOST_FCB *Fcb = NULL;
  EFI_STATUS   Status;
  CHAR8        *FileName;
  UINTN        NameSize;

  Fcb = SEMIHOST_FCB_FROM_THIS(File);

  if (!Fcb->IsRoot) {
    // Get the filename from the Fcb
    NameSize = AsciiStrLen (Fcb->FileName);
    FileName = AllocatePool (NameSize + 1);

    AsciiStrCpy (FileName, Fcb->FileName);

    // Close the file if it's open.  Disregard return status,
    // since it might give an error if the file isn't open.
    File->Close (File);

    // Call the semihost interface to delete the file.
    Status = SemihostFileRemove (FileName);
  } else {
    Status = EFI_UNSUPPORTED;
  }

  return Status;
}
Exemplo n.º 3
0
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 */
    AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);

    // move pointer to next tag
    mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
  }
Exemplo n.º 4
0
Arquivo: plist.c Projeto: weixu8/Duet
CHAR8* NewSymbol(CHAR8* string)
{
	SymbolPtr	lastGuy = 0;
	SymbolPtr	symbol;

	// Look for string in the list of symbols.
	symbol = FindSymbol(string, 0);

	// Add the new symbol.
	if (symbol == NULL)
	{
		
		symbol = (SymbolPtr)AllocateZeroPool(sizeof(Symbol) + 1 + AsciiStrLen(string));
		if (symbol == NULL) 
			return NULL;

		// Set the symbol's data.
		symbol->refCount = 0;
		
		AsciiStrCpy(symbol->string, string);

		// Add the symbol to the list.
		symbol->next = gSymbolsHead;
		gSymbolsHead = symbol;
	}

	// Update the refCount and return the string.
	symbol->refCount++;

	if (lastGuy && lastGuy->next != 0) 
		return NULL;

	return symbol->string;
}
Exemplo n.º 5
0
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_FILE *File,
  IN  CHAR16          *FileNameUnicode
  )
{
  CHAR8                 *FileNameAscii;
  UINT16                 SavedChar;
  UINTN                  FileNameSize;
  BOOTMON_FS_FILE       *SameFile;
  EFI_STATUS             Status;

  // EFI Shell inserts '\' in front of the filename that must be stripped
  if (FileNameUnicode[0] == L'\\') {
    FileNameUnicode++;
  }
  //
  // Convert Unicode into Ascii
  //
  SavedChar = L'\0';
  FileNameSize = StrLen (FileNameUnicode) + 1;
  FileNameAscii = AllocatePool (FileNameSize * sizeof (CHAR8));
  if (FileNameAscii == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  // If Unicode string is too long then truncate it.
  if (FileNameSize > MAX_NAME_LENGTH) {
    SavedChar = FileNameUnicode[MAX_NAME_LENGTH - 1];
    FileNameUnicode[MAX_NAME_LENGTH - 1] = L'\0';
  }
  UnicodeStrToAsciiStr (FileNameUnicode, FileNameAscii);
  // If the unicode string was truncated then restore its original content.
  if (SavedChar != L'\0') {
    FileNameUnicode[MAX_NAME_LENGTH - 1] = SavedChar;
  }

  // If we're changing the file name
  if (AsciiStrCmp (FileNameAscii, File->HwDescription.Footer.Filename) == 0) {
    // No change to filename.
    Status = EFI_SUCCESS;
  } else if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
    // You can only change the filename if you open the file for write.
    Status = EFI_ACCESS_DENIED;
  } else if (BootMonGetFileFromAsciiFileName (
                File->Instance,
                File->HwDescription.Footer.Filename,
                &SameFile) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    Status = EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrCpy (FileNameAscii, File->HwDescription.Footer.Filename);
    Status = EFI_SUCCESS;
  }

  FreePool (FileNameAscii);
  return Status;
}
Exemplo n.º 6
0
/**

  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 PcdDebugPrintErrorLevel, then print 
  the message specified by Format and the associated variable argument list to 
  the debug output device.

  If Format is NULL, then ASSERT().

  @param  ErrorLevel  The error level of the debug message.
  @param  Format      Format string for the debug message to print.

**/
VOID
EFIAPI
DebugPrint (
  IN  UINTN        ErrorLevel,
  IN  CONST CHAR8  *Format,
  ...
  )
{
  UINT64          Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)];
  EFI_DEBUG_INFO  *DebugInfo;
  UINTN           TotalSize;
  UINTN           Index;
  VA_LIST         Marker;
  UINT64          *ArgumentPointer;

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

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

  TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrLen (Format) + 1;
  if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {
    return;
  }

  //
  // Then EFI_DEBUG_INFO
  //
  DebugInfo = (EFI_DEBUG_INFO *)Buffer;
  DebugInfo->ErrorLevel = (UINT32)ErrorLevel;

  //
  // 256 byte mini Var Arg stack. That is followed by the format string.
  //
  VA_START (Marker, Format);
  for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) {
    WriteUnaligned64(ArgumentPointer, VA_ARG (Marker, UINT64));
  }
  VA_END (Marker);
  AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format);

  REPORT_STATUS_CODE_EX (
    EFI_DEBUG_CODE,
    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),
    0,
    NULL,
    &gEfiStatusCodeDataTypeDebugGuid,
    DebugInfo,
    TotalSize
    );
}
Exemplo n.º 7
0
/**
  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 = NULL;
  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;

  AsciiStrCpy (GaugeString, " ");

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

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

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

  return ;
}
Exemplo n.º 8
0
EFI_STATUS
ArmFastbootPlatformGetVar (
  IN  CHAR8   *Name,
  OUT CHAR8   *Value
  )
{
  if (AsciiStrCmp (Name, "product")) {
    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
  } else {
    *Value = '\0';
  }
  return EFI_SUCCESS;
}
Exemplo n.º 9
0
/**
  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) {
        AsciiStrCpy (GaugeString, " ");
    } else {
        StartIndex = 0;
        for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
            ;

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

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

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

        GaugeString[Index1] = 0;
    }

    return ;
}
Exemplo n.º 10
0
/**
  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.

  @return the length of the number after transform.

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

  Index           = 63;
  TempStr[Index]  = 0;

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

  AsciiStrCpy (Buffer, &TempStr[Index]);

  return AsciiStrLen (Buffer);
}
Exemplo n.º 11
0
/**
  Close and delete a file.

  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
                    handle to delete.

  @retval  EFI_SUCCESS              The file was closed and deleted.
  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.
  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL.

**/
EFI_STATUS
FileDelete (
  IN EFI_FILE *This
  )
{
  SEMIHOST_FCB   *Fcb;
  RETURN_STATUS  Return;
  CHAR8          *FileName;
  UINTN          NameSize;

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

  Fcb = SEMIHOST_FCB_FROM_THIS (This);

  if (!Fcb->IsRoot) {
    // Get the filename from the Fcb
    NameSize = AsciiStrLen (Fcb->FileName);
    FileName = AllocatePool (NameSize + 1);

    AsciiStrCpy (FileName, Fcb->FileName);

    // Close the file if it's open.  Disregard return status,
    // since it might give an error if the file isn't open.
    This->Close (This);

    // Call the semihost interface to delete the file.
    Return = SemihostFileRemove (FileName);
    if (RETURN_ERROR (Return)) {
      return EFI_WARN_DELETE_FAILURE;
    }
    return EFI_SUCCESS;
  } else {
    return EFI_WARN_DELETE_FAILURE;
  }
}
Exemplo n.º 12
0
/**
  Check every return package for update PRT

  @param AcpiSdt          Pointer to Acpi SDT protocol
  @param ParentHandle     ACPI pci device handle
  @param PciDeviceInfo    Pointer to PCI_DEVICE_INFO

**/
VOID
SdtCheckReturnPackage (
  IN EFI_ACPI_SDT_PROTOCOL  *AcpiSdt,
  IN EFI_ACPI_HANDLE        MethodHandle,
  IN PCI_DEVICE_INFO        *PciDeviceInfo
  )
{
  EFI_ACPI_HANDLE    PreviousHandle;
  EFI_ACPI_HANDLE    ReturnHandle;
  EFI_ACPI_HANDLE    PackageHandle;
  EFI_ACPI_HANDLE    NamePkgHandle;
  EFI_STATUS         Status;
  EFI_ACPI_DATA_TYPE DataType;
  UINT8              *Data;
  UINTN              DataSize;
  CHAR8              NameStr[128];

  ReturnHandle = NULL;
  while (TRUE) {
    PreviousHandle = ReturnHandle;
    Status = AcpiSdt->GetChild (MethodHandle, &ReturnHandle);
    ASSERT_EFI_ERROR (Status);

    if (PreviousHandle != NULL) {
      Status = AcpiSdt->Close (PreviousHandle);
      ASSERT_EFI_ERROR (Status);
    }

    if (ReturnHandle == NULL) {
      break;
    }

    Status = AcpiSdt->GetOption (ReturnHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
    ASSERT_EFI_ERROR (Status);
    ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);

    if (*Data == AML_RETURN_OP) {
      //
      // Find the return method handle, then look for the returned package data
      //
      Status = AcpiSdt->GetOption (ReturnHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
      ASSERT_EFI_ERROR (Status);


      if (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING) {
        ZeroMem (NameStr, 128);
        AsciiStrCpy (NameStr, "\\_SB.");
        DataSize = SdtGetNameStringSize (Data);
        AsciiStrnCat (NameStr, (CHAR8 *)Data, DataSize);

        NamePkgHandle = NULL;
        Status = AcpiSdt->FindPath (mDsdtHandle, NameStr, &NamePkgHandle);
        ASSERT_EFI_ERROR (Status);
        ASSERT (NamePkgHandle != NULL);

        Status = AcpiSdt->GetOption (NamePkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
        ASSERT_EFI_ERROR (Status);
        ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
        ASSERT (*Data == AML_NAME_OP);

        Status = AcpiSdt->GetOption (NamePkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
        ASSERT_EFI_ERROR (Status);
        ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
      }

      ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);

      //
      // Get the parent package handle
      //
      PackageHandle = NULL;
      Status = AcpiSdt->Open (Data, &PackageHandle);
      ASSERT_EFI_ERROR (Status);

      //
      // Check the parent package for update pci routing
      //
      SdtCheckParentPackage (AcpiSdt, PackageHandle, PciDeviceInfo);

      Status = AcpiSdt->Close (PackageHandle);
      ASSERT_EFI_ERROR (Status);

      Status = AcpiSdt->Close (ReturnHandle);
      ASSERT_EFI_ERROR (Status);

      break;
    }

    //
    // Not ReturnOp, search it as parent
    //
    SdtCheckReturnPackage (AcpiSdt, ReturnHandle, PciDeviceInfo);
  }

  //
  // Done
  //
  return;

}
Exemplo n.º 13
0
/**

  Allocates a block of memory and writes performance data of booting into it.
  OS can processing these record.

**/
VOID
WriteBootToOsPerformanceData (
    VOID
)
{
    EFI_STATUS                Status;
    UINT32                    AcpiLowMemoryLength;
    UINT32                    LimitCount;
    EFI_HANDLE                *Handles;
    UINTN                     NoHandles;
    CHAR8                     GaugeString[PERF_TOKEN_LENGTH];
    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;

    //
    // 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;
    }

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


    AcpiLowMemoryLength = 0x4000;
    if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
        //
        // Allocate a block of memory that contain performance data to OS
        //
        Status = gBS->AllocatePages (
                     AllocateMaxAddress,
                     EfiReservedMemoryType,
                     EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),
                     &mAcpiLowMemoryBase
                 );
        if (EFI_ERROR (Status)) {
            FreePool (Handles);
            return ;
        }
    }


    Ptr        = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
    LimitCount = (AcpiLowMemoryLength - 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);

            AsciiStrCpy (mPerfData.Token, 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));

            AsciiStrnCpy (mPerfData.Token, 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)
    );

    gRT->SetVariable (
        L"PerfDataMemAddr",
        &gPerformanceProtocolGuid,
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        sizeof (EFI_PHYSICAL_ADDRESS),
        &mAcpiLowMemoryBase
    );

    return ;
}
Exemplo n.º 14
0
/**
Open a device named by PathName. The PathName includes a device name and
path separated by a :. See file header for more details on the PathName
syntax. There is no checking to prevent a file from being opened more than
one type.

SectionType is only used to open an FV. Each file in an FV contains multiple
sections and only the SectionType section is opened.

For any file that is opened with EfiOpen() must be closed with EfiClose().

@param  PathName    Path to parse to open
@param  OpenMode    Same as EFI_FILE.Open()
@param  SectionType Section in FV to open.

@return NULL  Open failed
@return Valid EFI_OPEN_FILE handle

**/
EFI_OPEN_FILE *
EfiOpen (
  IN        CHAR8               *PathName,
  IN  CONST UINT64              OpenMode,
  IN  CONST EFI_SECTION_TYPE    SectionType
  )
{
  EFI_STATUS                Status;
  EFI_OPEN_FILE             *File;
  EFI_OPEN_FILE             FileData;
  UINTN                     StrLen;
  UINTN                     FileStart;
  UINTN                     DevNumber = 0;
  EFI_OPEN_FILE_GUARD       *GuardFile;
  BOOLEAN                   VolumeNameMatch;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     Size;
  EFI_IP_ADDRESS            Ip;
  CHAR8                     *CwdPlusPathName;
  UINTN                     Index;
  EFI_SECTION_TYPE          ModifiedSectionType;

  EblUpdateDeviceLists ();

  File = &FileData;
  ZeroMem (File, sizeof (EFI_OPEN_FILE));

  StrLen = AsciiStrSize (PathName);
  if (StrLen <= 1) {
    // Smallest valid path is 1 char and a null
    return NULL;
  }

  for (FileStart = 0; FileStart < StrLen; FileStart++) {
    if (PathName[FileStart] == ':') {
      FileStart++;
      break;
    }
  }

  //
  // Matching volume name has precedence over handle based names
  //
  VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
  if (!VolumeNameMatch) {
    if (FileStart == StrLen) {
      // No Volume name or device name, so try Current Working Directory
      if (gCwd == NULL) {
        // No CWD
        return NULL;
      }

      // We could add a current working directory concept
      CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
      if (CwdPlusPathName == NULL) {
        return NULL;
      }

      if ((PathName[0] == '/') || (PathName[0] == '\\')) {
        // PathName starts in / so this means we go to the root of the device in the CWD.
        CwdPlusPathName[0] = '\0';
        for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
          CwdPlusPathName[FileStart] = gCwd[FileStart];
          if (gCwd[FileStart] == ':') {
            FileStart++;
            CwdPlusPathName[FileStart] = '\0';
            break;
          }
        }
      } else {
        AsciiStrCpy (CwdPlusPathName, gCwd);
        StrLen = AsciiStrLen (gCwd);
        if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
          AsciiStrCat (CwdPlusPathName, "\\");
        }
      }

      AsciiStrCat (CwdPlusPathName, PathName);
      if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
        // Extra error check to make sure we don't recurse and blow stack
        return NULL;
      }

      File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
      FreePool (CwdPlusPathName);
      return File;
    }

    DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName);
  }

  File->DeviceName = AllocatePool (StrLen);
  AsciiStrCpy (File->DeviceName, PathName);
  File->DeviceName[FileStart - 1] = '\0';
  File->FileName = &File->DeviceName[FileStart];
  if (File->FileName[0] == '\0') {
    // if it is just a file name use / as root
    File->FileName = "\\";
  }

  //
  // Use best match algorithm on the dev names so we only need to look at the
  // first few charters to match the full device name. Short name forms are
  // legal from the caller.
  //
  Status = EFI_SUCCESS;
  if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
    if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
      if (DevNumber >= mFsCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFileSystem;
      File->EfiHandle = mFs[DevNumber];
      Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);

    } else if (PathName[1] == 'v' || PathName[1] == 'V') {
      if (DevNumber >= mFvCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFirmwareVolume;
      File->EfiHandle = mFv[DevNumber];

      if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
        // Skip leading / as its not really needed for the FV since no directories are supported
        FileStart++;
      }

      // Check for 2nd :
      ModifiedSectionType = SectionType;
      for (Index = FileStart; PathName[Index] != '\0'; Index++) {
        if (PathName[Index] == ':') {
          // Support fv0:\DxeCore:0x10
          // This means open the PE32 Section of the file
          ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
          PathName[Index] = '\0';
        }
      }
      File->FvSectionType = ModifiedSectionType;
      Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
    }
  } else if ((*PathName == 'A') || (*PathName == 'a')) {
    // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
    File->Type = EfiOpenMemoryBuffer;
    // 1st colon is at PathName[FileStart - 1]
    File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      File->Size = 0;
    } else {
      File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if there's no number after the second colon, default
    // the end of memory
    if (File->Size == 0) {
      File->Size =  (UINTN)(0 - (UINTN)File->Buffer);
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = (UINTN)File->Buffer;

  } else if (*PathName== 'l' || *PathName == 'L') {
    if (DevNumber >= mLoadFileCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenLoadFile;
    File->EfiHandle = mLoadFile[DevNumber];

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
    File->DevicePath = DuplicateDevicePath (DevicePath);

  } else if (*PathName == 'b' || *PathName == 'B') {
    // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
    if (DevNumber >= mBlkIoCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenBlockIo;
    File->EfiHandle = mBlkIo[DevNumber];
    EblFileDevicePath (File, "", OpenMode);

    // 1st colon is at PathName[FileStart - 1]
    File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      Size = 0;
    } else {
      Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if a zero size is passed in (or the size is left out entirely),
    // go to the end of the device.
    if (Size == 0) {
      File->Size = File->Size - File->DiskOffset;
    } else {
      File->Size = Size;
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = File->DiskOffset;
  } else if ((*PathName) >= '0' && (*PathName <= '9')) {

    // Get current IP address
    Status = EblGetCurrentIpAddress (&Ip);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Device IP Address is not configured.\n");
      goto ErrorExit;
    }


    // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
    File->Type = EfiOpenTftp;
    File->IsDirty = FALSE;
    File->IsBufferValid = FALSE;

    Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
  if (GuardFile == NULL) {
    goto ErrorExit;
  }

  GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
  CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
  GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;

  return &(GuardFile->File);

ErrorExit:
  FreePool (File->DeviceName);
  return NULL;
}
Exemplo n.º 15
0
/**
  Extract the Root Path option and get the required target information from
  Boot File Uniform Resource Locator (URL) Option.

  @param[in]       RootPath      The RootPath string.
  @param[in]       Length        Length of the RootPath option payload.
  @param[in, out]  ConfigData    The iSCSI session configuration data read from
                                 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
IScsiDhcp6ExtractRootPath (
  IN     CHAR8                        *RootPath,
  IN     UINT16                       Length,
  IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
  )
{
  EFI_STATUS                  Status;
  UINT16                      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 = (UINT16) 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 = RootPath + IScsiRootPathIdLen;
  Length   = (UINT16) (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      = 0;
  ZeroMem (&Fields[0], sizeof (Fields));

  //
  // Extract SERVERNAME field in the Root Path option.
  //
  if (TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_START_DELIMITER) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  } else {
    Index++;
  }

  Fields[RP_FIELD_IDX_SERVERNAME].Str = &TmpStr[Index];

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

  //
  // Skip ']' and ':'.
  //
  TmpStr[Index] = '\0';
  Index += 2;

  Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8) AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);

  //
  // Extract others fields in the Root Path option string.
  //
  for (FieldIndex = 1; (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;
  }

  AsciiStrCpy (ConfigNvData->TargetName, Field->Str);

ON_EXIT:

  FreePool (TmpStr);

  return Status;
}
Exemplo n.º 16
0
/**
  Start an EFI image (PE32+ with EFI defined entry point).

  Argv[0] - "start"
  Argv[1] - device name and path
  Argv[2] - "" string to pass into image being started

  start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
                                      ; ascii string arg to pass to the image
  start fv0:\FV                       ; load an FV from an FV (not common)
  start LoadFile0:                    ; load an FV via a PXE boot

  @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
EblStartCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                  Status;
  EFI_OPEN_FILE               *File;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  EFI_HANDLE                  ImageHandle;
  UINTN                       ExitDataSize;
  CHAR16                      *ExitData;
  VOID                        *Buffer;
  UINTN                       BufferSize;
  EFI_LOADED_IMAGE_PROTOCOL   *ImageInfo;

  ImageHandle = NULL;

  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DevicePath = File->DevicePath;
  if (DevicePath != NULL) {
    // check for device path form: blk, fv, fs, and loadfile
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
  } else {
    // Check for buffer form: A0x12345678:0x1234 syntax.
    // Means load using buffer starting at 0x12345678 of size 0x1234.

    Status = EfiReadAllocatePool (File, &Buffer, &BufferSize);
    if (EFI_ERROR (Status)) {
      EfiClose (File);
      return Status;
    }
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);

    FreePool (Buffer);
  }

  EfiClose (File);

  if (!EFI_ERROR (Status)) {
    if (Argc >= 3) {
      // Argv[2] is a "" string that we pass directly to the EFI application without the ""
      // We don't pass Argv[0] to the EFI Application (it's name) just the args
      Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);
      ASSERT_EFI_ERROR (Status);

      ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]);
      ImageInfo->LoadOptions     = AllocatePool (ImageInfo->LoadOptionsSize);
      AsciiStrCpy (ImageInfo->LoadOptions, Argv[2]);
    }

    // Transfer control to the EFI image we loaded with LoadImage()
    Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
  }

  return Status;
}
Exemplo n.º 17
0
EFI_STATUS
EblFileCopyCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_OPEN_FILE *Source      = NULL;
  EFI_OPEN_FILE *Destination = NULL;
  EFI_STATUS    Status       = EFI_SUCCESS;
  VOID          *Buffer      = NULL;
  UINTN         Size;
  UINTN         Offset;
  UINTN         Chunk        = FILE_COPY_CHUNK;
  UINTN         FileNameLen;
  CHAR8*        DestFileName;
  CHAR8*        SrcFileName;
  CHAR8*        SrcPtr;

  if (Argc < 3) {
    return EFI_INVALID_PARAMETER;
  }

  DestFileName = Argv[2];
  FileNameLen = AsciiStrLen (DestFileName);

  // Check if the destination file name looks like a directory
  if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) {
    // Set the pointer after the source drive (eg: after fs1:)
    SrcPtr = AsciiStrStr (Argv[1], ":");
    if (SrcPtr == NULL) {
      SrcPtr = Argv[1];
    } else {
      SrcPtr++;
      if (*SrcPtr == '\\') {
        SrcPtr++;
      }
    }

    if (*SrcPtr == '\0') {
      AsciiPrint("Source file incorrect.\n");
    }

    // Skip the Source Directories
    while (1) {
      SrcFileName = SrcPtr;
      SrcPtr = AsciiStrStr (SrcPtr,"\\");
      if (SrcPtr != NULL) {
        SrcPtr++;
      } else {
        break;
      }
    }

    if (*SrcFileName == '\0') {
      AsciiPrint("Source file incorrect (Error 2).\n");
    }

    // Construct the destination filepath
    DestFileName = (CHAR8*)AllocatePool (FileNameLen + AsciiStrLen (SrcFileName) + 1);
    AsciiStrCpy (DestFileName, Argv[2]);
    AsciiStrCat (DestFileName, SrcFileName);
  }

  Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);
  if (Source == NULL) {
    AsciiPrint("Source file open error.\n");
    return EFI_NOT_FOUND;
  }

  Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
  if (Destination == NULL) {
    AsciiPrint("Destination file open error.\n");
    return EFI_NOT_FOUND;
  }

  Buffer = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer == NULL) {
    goto Exit;
  }

  Size = EfiTell(Source, NULL);

  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
    Chunk = FILE_COPY_CHUNK;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error %r\n", Status);
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error %r\n", Status);
      goto Exit;
    }
  }

  // Any left over?
  if (Offset < Size) {
    Chunk = Size - Offset;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error %r\n", Status);
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error %r\n", Status);
      goto Exit;
    }
  }


Exit:
  if (Source != NULL) {
    Status = EfiClose(Source);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Source close error %r\n", Status);
    }
  }
  if (Destination != NULL) {
    Status = EfiClose(Destination);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Destination close error %r\n", Status);
    }

    // Case when we have concated the filename to the destination directory
    if (DestFileName != Argv[2]) {
      FreePool (DestFileName);
    }
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  return Status;
}
Exemplo n.º 18
0
/**
  Changes the state of a network interface from "stopped" to "started".

  @param  This Protocol instance pointer.

  @retval EFI_SUCCESS           The network interface was started.
  @retval EFI_ALREADY_STARTED   The network interface is already in the started state.
  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

**/
EFI_STATUS
EmuSnpStart (
  IN EMU_SNP_PROTOCOL  *This
  )
{
  EFI_STATUS         Status;
  EMU_SNP_PRIVATE    *Private;
  struct ifreq       BoundIf;
  struct bpf_program BpfProgram;
  struct bpf_insn    *FilterProgram;
	u_int							 Value;
	u_int  						 ReadBufferSize;
  UINT16             Temp16;
  UINT32             Temp32;

  Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This);

  switch (Private->Mode->State) {
    case EfiSimpleNetworkStopped:
      break;

    case EfiSimpleNetworkStarted:
    case EfiSimpleNetworkInitialized:
      return EFI_ALREADY_STARTED;
      break;

    default:
      return EFI_DEVICE_ERROR;
      break;
  }

  Status = EFI_SUCCESS;
  if (Private->BpfFd == 0) {
    Status = OpenBpfFileDescriptor (Private, &Private->BpfFd);
    if (EFI_ERROR (Status)) {
      goto DeviceErrorExit;
    }

    //
		// Get the read buffer size.
		//
		if (ioctl (Private->BpfFd, BIOCGBLEN, &ReadBufferSize) < 0) {
			goto DeviceErrorExit;
		}

		//
		// Default value from BIOCGBLEN is usually too small, so use a much larger size, if necessary.
		//
		if (ReadBufferSize < FixedPcdGet32 (PcdNetworkPacketFilterSize)) {
			ReadBufferSize = FixedPcdGet32 (PcdNetworkPacketFilterSize);
			if (ioctl (Private->BpfFd, BIOCSBLEN, &ReadBufferSize) < 0) {
				goto DeviceErrorExit;
			}
		}

		//
    // Associate our interface with this BPF file descriptor.
    //
    AsciiStrCpy (BoundIf.ifr_name, Private->InterfaceName);
    if (ioctl (Private->BpfFd, BIOCSETIF, &BoundIf) < 0) {
      goto DeviceErrorExit;
    }

    //
		// Enable immediate mode.
    //
    Value = 1;
    if (ioctl (Private->BpfFd, BIOCIMMEDIATE, &Value) < 0) {
      goto DeviceErrorExit;
    }

    //
    // Enable non-blocking I/O.
    //
    if (fcntl (Private->BpfFd, F_GETFL, 0) == -1) {
      goto DeviceErrorExit;
    }

    Value |= O_NONBLOCK;

    if (fcntl (Private->BpfFd, F_SETFL, Value) == -1) {
      goto DeviceErrorExit;
    }

    //
    // Disable "header complete" flag.  This means the supplied source MAC address is
    // what goes on the wire.
    //
    Value = 1;
    if (ioctl (Private->BpfFd, BIOCSHDRCMPLT, &Value) < 0) {
      goto DeviceErrorExit;
    }

    //
    // Allocate read buffer.
    //
		Private->ReadBufferSize = ReadBufferSize;
		Private->ReadBuffer = malloc (Private->ReadBufferSize);
    if (Private->ReadBuffer == NULL) {
      goto ErrorExit;
    }

    Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer;

    //
		// Install our packet filter: successful reads should only produce broadcast or unicast
    // packets directed to our fake MAC address.
    //
    FilterProgram = malloc (sizeof (mFilterInstructionTemplate)) ;
    if ( FilterProgram == NULL ) {
      goto ErrorExit;
    }

    CopyMem (FilterProgram, &mFilterInstructionTemplate, sizeof (mFilterInstructionTemplate));

    //
    // Insert out fake MAC address into the filter.  The data has to be host endian.
    //
    CopyMem (&Temp32, &Private->Mode->CurrentAddress.Addr[0], sizeof (UINT32));
    FilterProgram[1].k = NTOHL (Temp32);
    CopyMem (&Temp16, &Private->Mode->CurrentAddress.Addr[4], sizeof (UINT16));
    FilterProgram[3].k = NTOHS (Temp16);

    BpfProgram.bf_len = sizeof (mFilterInstructionTemplate) / sizeof (struct bpf_insn);
    BpfProgram.bf_insns = FilterProgram;

    if (ioctl (Private->BpfFd, BIOCSETF, &BpfProgram) < 0) {
      goto DeviceErrorExit;
    }

    free (FilterProgram);

    //
    // Enable promiscuous mode.
    //
    if (ioctl (Private->BpfFd, BIOCPROMISC, 0) < 0) {
      goto DeviceErrorExit;
    }


    Private->Mode->State = EfiSimpleNetworkStarted;
  }

  return Status;

DeviceErrorExit:
  Status = EFI_DEVICE_ERROR;
ErrorExit:
  if (Private->ReadBuffer != NULL) {
    free (Private->ReadBuffer);
    Private->ReadBuffer = NULL;
  }
  return Status;
}
Exemplo n.º 19
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
    //
    AsciiStrCpy (Entry, "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;
}
Exemplo n.º 20
0
VOID
SetDMISettingsForModel (
  MACHINE_TYPES Model
  )
{
  AsciiStrCpy (gSettings.VendorName,           BiosVendor);
  AsciiStrCpy (gSettings.RomVersion,           AppleFirmwareVersion[Model]);
  AsciiStrCpy (gSettings.ReleaseDate,          AppleReleaseDate[Model]);
  AsciiStrCpy (gSettings.ManufactureName,      BiosVendor);
  AsciiStrCpy (gSettings.ProductName,          AppleProductName[Model]);
  AsciiStrCpy (gSettings.VersionNr,            AppleSystemVersion[Model]);
  AsciiStrCpy (gSettings.SerialNr,             AppleSerialNumber[Model]);
  AsciiStrCpy (gSettings.FamilyName,           AppleFamilies[Model]);
  AsciiStrCpy (gSettings.BoardManufactureName, BiosVendor);
  AsciiStrCpy (gSettings.BoardSerialNumber,    AppleBoardSN);
  AsciiStrCpy (gSettings.BoardNumber,          AppleBoardID[Model]);
  AsciiStrCpy (gSettings.BoardVersion,         AppleProductName[Model]);
  AsciiStrCpy (gSettings.LocationInChassis,    AppleBoardLocation);
  AsciiStrCpy (gSettings.ChassisManufacturer,  BiosVendor);
  AsciiStrCpy (gSettings.ChassisAssetTag,      AppleChassisAsset[Model]);
  
  if (Model >= MacPro31) {
    gSettings.BoardType = BaseBoardTypeProcessorMemoryModule; //11;
  } else {
    gSettings.BoardType = BaseBoardTypeMotherBoard; //10; 
  }

  switch (Model) {
    case MacBook11:
    case MacBook21:
    case MacBook41:
    case MacBook52:
    case MacBookAir31:
    case MacBookAir52:
    case MacBookAir62:  
    case MacBookPro111:
      gSettings.ChassisType = MiscChassisTypeNotebook; //10; 
      gSettings.Mobile      = TRUE;
      break;

    case MacBookPro51:
    case MacBookPro62:
    case MacBookPro81:
    case MacBookPro83:
    case MacBookPro92:
	case MacBookPro101:
    gSettings.ChassisType = MiscChassisTypePortable; //08;
    gSettings.Mobile      = TRUE;
    break;

    case iMac81:
    case iMac101:
    case iMac111:
    case iMac112:
    case iMac113:
    case iMac121:
    case iMac122:
    case iMac131:
    case iMac132:
    case iMac141:
    case iMac142:
    case iMac151:
      gSettings.ChassisType = MiscChassisTypeAllInOne; //13; 
      gSettings.Mobile      = FALSE;
      break;

    case MacMini21:
    case MacMini51:
    case MacMini62:  
      gSettings.ChassisType = MiscChassisTypeLunchBox; //16; 
      gSettings.Mobile      = FALSE;
      break;

    case MacPro31:
    case MacPro41:
    case MacPro51:
      gSettings.ChassisType = MiscChassisTypeMiniTower; //06; 
      gSettings.Mobile      = FALSE;
      break; 

    case MacPro61:
      gSettings.ChassisType = MiscChassisTypeUnknown;  //02; this is a joke but think different!
      gSettings.Mobile      = FALSE;
      break; 
      
    default: //unknown - use oem SMBIOS value to be default
      gSettings.Mobile      = gMobile;
      gSettings.ChassisType = 0; //let SMBIOS value to be
/*      if (gMobile) {
        gSettings.ChassisType = 10; //notebook
      } else {
        gSettings.ChassisType = MiscChassisTypeDeskTop; //03; 
      } */
      break;
  }
 //smc helper
  if (SmcPlatform[Model][0] != 'N') {
    AsciiStrCpy (gSettings.RPlt, SmcPlatform[Model]);
  } else {
    switch (gCPUStructure.Model) {
      case CPU_MODEL_PENTIUM_M:
        AsciiStrCpy (gSettings.RPlt, "M70");
        break;

      case CPU_MODEL_YONAH:
        AsciiStrCpy (gSettings.RPlt, "k22");
        break;

      case CPU_MODEL_MEROM: //TODO check for mobile
        AsciiStrCpy (gSettings.RPlt, "M75");
        break;

      case CPU_MODEL_PENRYN:
        if (gSettings.Mobile) {
          AsciiStrCpy (gSettings.RPlt, "M82");
        } else {
          AsciiStrCpy (gSettings.RPlt, "k36");
        }
        break;

      case CPU_MODEL_SANDY_BRIDGE:
        if (gSettings.Mobile) {
          AsciiStrCpy (gSettings.RPlt, "k90i");
        } else {
          AsciiStrCpy (gSettings.RPlt, "k60");
        }
        break;

      case CPU_MODEL_IVY_BRIDGE:
        AsciiStrCpy (gSettings.RPlt, "j30");
        break;

      case CPU_MODEL_IVY_BRIDGE_E5:
        AsciiStrCpy (gSettings.RPlt, "j90");
        break;

      case CPU_MODEL_HASWELL_ULT:
        AsciiStrCpy (gSettings.RPlt, "j44");
        break;

      default:
        AsciiStrCpy (gSettings.RPlt, "T9");
        break;
    }
  }

  CopyMem (gSettings.REV,  SmcRevision[Model], 6);
  AsciiStrCpy (gSettings.RBr,  gSettings.RPlt); //SmcBranch[Model]); // as no other ideas
  CopyMem (gSettings.EPCI, &SmcConfig[Model],  4);
}
Exemplo n.º 21
0
/**
  Fill a standard Smbios string field. 
  
  This function will convert the unicode string to single byte chars, and only
  English language is supported.
  This function changes the Structure pointer value of the structure node, 
  which should be noted by Caller.
  
  @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
  @param Offset           Offset of SMBIOS record which RecordData will be filled.
  @param RecordData       RecordData buffer will be filled.
  @param RecordDataSize   The size of RecordData buffer.
  
  @retval EFI_INVALID_PARAMETER   RecordDataSize is too larger
  @retval EFI_OUT_OF_RESOURCES    No memory to allocate new buffer for string
  @retval EFI_SUCCESS             Sucess append string for a SMBIOS record.
**/
EFI_STATUS
SmbiosFldString (
  IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
  IN      UINT32                    Offset,
  IN      VOID                      *RecordData,
  IN      UINT32                    RecordDataSize
  )
{
  EFI_STATUS              Status;
  UINT16                  *Data;
  CHAR8                   AsciiData[SMBIOS_STRING_MAX_LENGTH];
  UINT8                   CountOfStrings;
  UINTN                   OrigStringNumber;
  EFI_SMBIOS_PROTOCOL     *Smbios;
  EFI_SMBIOS_HANDLE       SmbiosHandle;
  UINT32                  OrigStructureSize;
  UINTN                   NewStructureSize;
  EFI_SMBIOS_TABLE_HEADER *NewRecord;
  UINT32                  StringLength;
  
  Status            = EFI_SUCCESS;
  OrigStringNumber  = 0;
  OrigStructureSize = 0;

  //
  // if we have a NULL token,
  //
  if (0 == *((STRING_REF *) RecordData)) {
    *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
    return EFI_SUCCESS;
  }
  
  //
  // Get the String from the Hii Database
  //
  Data = HiiGetPackageString (
             &(StructureNode->ProducerName),
             *((EFI_STRING_ID *) RecordData),
             NULL
             );
  if (Data == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  StringLength = (UINT32)StrLen (Data);
  //
  // Count the string size including the terminating 0.
  //
  if (StringLength == 0) {
    *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
    FreePool (Data);
    return EFI_SUCCESS;
  }
  
  if (StringLength > SMBIOS_STRING_MAX_LENGTH) {
    //
    // Too long a string
    //
    FreePool (Data);
    return EFI_INVALID_PARAMETER;
  }
    
  Smbios = GetSmbiosProtocol();
  ASSERT (Smbios != NULL);
  
  //
  // Convert Unicode string to Ascii string which only supported by SMBIOS.
  //
  ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH);
  UnicodeStrToAsciiStr (Data, AsciiData);
  
  //
  // if the field at offset is already filled with some value,
  // find out the string it points to
  //
  OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset);
  if (OrigStringNumber != 0) {
    DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n", 
            OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData));  
    
    //
    // If original string number is not zero, just update string
    //
    Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n", 
             OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType));
      ASSERT_EFI_ERROR (Status);
      return Status;
    }
  } else {
    //
    // If the string has not been filled in SMBIOS database, remove it and add again
    // with string appended.
    //
    Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings);
    ASSERT_EFI_ERROR (Status);
    
    if (CountOfStrings == 0) {
      NewStructureSize = OrigStructureSize + StringLength;
    } else {
      NewStructureSize = OrigStructureSize + StringLength + 1;
    }
    
    NewRecord = AllocateZeroPool (NewStructureSize);
    if (NewRecord == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize);
    
    //
    // Copy new string into tail of original SMBIOS record buffer.
    //
    if (CountOfStrings == 0) {
      AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData);
    } else {
      AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData);
    }
    DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n", 
            StructureNode->SmbiosType, Offset, CountOfStrings + 1));
    //
    // Update string reference number
    //
    *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1);
    SmbiosHandle = StructureNode->SmbiosHandle;
    
    //
    // Remove original SMBIOS record and add new one
    //
    Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
    ASSERT_EFI_ERROR (Status);
    
    //
    // Add new SMBIOS record
    //
    Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord);
    ASSERT_EFI_ERROR (Status);
    
    StructureNode->SmbiosHandle = SmbiosHandle;
    
    FreePool (NewRecord);
  }
  
  //
  // The SMBIOS record buffer maybe re-allocated in SMBIOS database,
  // so update cached buffer pointer in DataHub structure list.
  //
  StructureNode->Structure = GetSmbiosBufferFromHandle (
                               StructureNode->SmbiosHandle, 
                               StructureNode->SmbiosType,
                               NULL
                               );
  ASSERT (StructureNode->Structure != NULL);
  
  //
  // The string update action maybe lead the record is re-allocated in SMBIOS database
  // so update cached record pointer
  //
  Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings);
  ASSERT_EFI_ERROR (Status);
  
  return EFI_SUCCESS;
}
Exemplo n.º 22
0
//
// Returns parsed hex integer key.
// Plist - kext pist
// Key - key to find
// WholePlist - _PrelinkInfoDictionary, used to find referenced values
//
// Searches for Key in Plist and it's value:
// a) <integer ID="26" size="64">0x2b000</integer>
//    returns 0x2b000
// b) <integer IDREF="26"/>
//    searches for <integer ID="26"... from WholePlist
//    and returns value from that referenced field
//
// Whole function is here since we should avoid ParseXML() and it's
// memory allocations during ExitBootServices(). And it seems that
// ParseXML() does not support IDREF.
// This func is hard to read and debug and probably not reliable,
// but it seems it works.
//
UINT64
GetPlistHexValue (
    CHAR8 *Plist,
    CHAR8 *Key,
    CHAR8 *WholePlist
)
{
    CHAR8     *Value;
    CHAR8     *IntTag;
    UINT64    NumValue;
    CHAR8     *IDStart;
    CHAR8     *IDEnd;
    UINTN     IDLen;
    CHAR8     Buffer[48];

    NumValue = 0;

    // search for Key
    Value = AsciiStrStr (Plist, Key);
    if (Value == NULL) {
        return 0;
    }
    // search for <integer
    IntTag = AsciiStrStr (Value, "<integer");
    if (IntTag == NULL) {
        return 0;
    }
    // find <integer end
    Value = AsciiStrStr (IntTag, ">");
    if (Value == NULL) {
        return 0;
    }
    // normal case: value is here
    if (Value[-1] != '/') {
        NumValue = AsciiStrHexToUint64 (Value + 1);
        return NumValue;
    }
    // it might be a reference: IDREF="173"/>
    Value = AsciiStrStr (IntTag, "<integer IDREF=\"");
    if (Value != IntTag) {
        return 0;
    }
    // compose <integer ID="xxx" in the Buffer
    IDStart = AsciiStrStr (IntTag, "\"") + 1;
    IDEnd = AsciiStrStr (IDStart, "\"");
    IDLen = IDEnd - IDStart;
    if (IDLen > 8) {
        return 0;
    }
    AsciiStrCpy (Buffer, "<integer ID=\"");
    AsciiStrnCat (Buffer, IDStart, IDLen);
    AsciiStrCat (Buffer, "\"");
    // and search whole plist for ID
    IntTag = AsciiStrStr (WholePlist, Buffer);
    if (IntTag == NULL) {
        return 0;
    }
    // got it. find closing >
    Value = AsciiStrStr (IntTag, ">");
    if (Value == NULL) {
        return 0;
    }
    if (Value[-1] == '/') {
        return 0;
    }
    // we should have value now
    NumValue = AsciiStrHexToUint64 (Value + 1);

    return NumValue;
}
Exemplo n.º 23
0
/**
  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;
  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
  //
  AsciiStrCpy (FormatString, 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') {
      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') {
Exemplo n.º 24
0
/**
  Do the diagnostics call for some set of handles.

  @param[in] Mode               The type of diagnostic test to run.
  @param[in] Lang               The language code to use.
  @param[in] AllChilds          Should the test be on all children.
  @param[in] DriverHandle       The driver handle to test with.
  @param[in] ControllerHandle   The specific controller handle to test.
  @param[in] ChildHandle        The specific child handle to test.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_INVALID_PARAMETER A parameter had an invalid value.
  @retval EFI_NOT_FOUND         No diagnostic handle could be found.
**/
EFI_STATUS
EFIAPI
DoDiagnostics (
  IN CONST DRV_DIAG_TEST_MODE Mode,
  IN CONST CHAR8              *Lang,
  IN CONST BOOLEAN            AllChilds,
  IN CONST EFI_HANDLE         DriverHandle,
  IN CONST EFI_HANDLE         ControllerHandle,
  IN CONST EFI_HANDLE         ChildHandle
  )
{
  EFI_DRIVER_DIAGNOSTICS_PROTOCOL     *DriverDiagnostics;
  EFI_DRIVER_DIAGNOSTICS2_PROTOCOL    *DriverDiagnostics2;
  EFI_HANDLE                          *DriverHandleList;
  EFI_HANDLE                          *ControllerHandleList;
  EFI_HANDLE                          *ChildHandleList;
  EFI_HANDLE                          *Walker;
  UINTN                               DriverHandleListCount;
  UINTN                               ControllerHandleListCount;
  UINTN                               ChildHandleListCount;
  UINTN                               DriverHandleListLoop;
  UINTN                               ControllerHandleListLoop;
  UINTN                               ChildHandleListLoop;
  EFI_STATUS                          Status;
  EFI_STATUS                          Status2;
  EFI_GUID                            *ErrorType;
  UINTN                               OutBufferSize;
  CHAR16                              *OutBuffer;
  UINTN                               HandleIndex1;
  UINTN                               HandleIndex2;
  CHAR8                               *Language;
  CHAR8                               *TempChar;
  BOOLEAN                             Found;

  if ((ChildHandle != NULL && AllChilds) || (Mode >= TestModeMax)){
    return (EFI_INVALID_PARAMETER);
  }

  DriverDiagnostics                   = NULL;
  DriverDiagnostics2                  = NULL;
  Status                              = EFI_SUCCESS;
  Status2                             = EFI_SUCCESS;
  DriverHandleList                    = NULL;
  ControllerHandleList                = NULL;
  ChildHandleList                     = NULL;
  Language                            = NULL;
  OutBuffer                           = NULL;
  ErrorType                           = NULL;
  DriverHandleListCount               = 0;
  ControllerHandleListCount           = 0;
  ChildHandleListCount                = 0;

  if (DriverHandle != NULL) {
    DriverHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
    ASSERT(DriverHandleList!=NULL);
    DriverHandleList[0] = DriverHandle;
    DriverHandleListCount = 1;
  } else {
    DriverHandleList = GetHandleListByProtocolList(DiagGuidList);
    if (DriverHandleList == NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiDriverDiagnosticsProtocolGuid", &gEfiDriverDiagnosticsProtocolGuid);
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiDriverDiagnostics2ProtocolGuid", &gEfiDriverDiagnostics2ProtocolGuid);
      return (EFI_NOT_FOUND);
    } 
    for (Walker = DriverHandleList ; Walker != NULL && *Walker != NULL ; DriverHandleListCount++, Walker++);
  }

  if (ControllerHandle != NULL) {
    ControllerHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
    ASSERT(ControllerHandleList!=NULL);
    ControllerHandleList[0] = ControllerHandle;
    ControllerHandleListCount = 1;
  } else {
    ControllerHandleList = NULL;
  }

  if (ChildHandle != NULL) {
    ChildHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
    ASSERT(ChildHandleList!=NULL);
    ChildHandleList[0] = ChildHandle;
    ChildHandleListCount = 1;
  } else if (AllChilds) {
    ChildHandleList = NULL;
    //
    // This gets handled in the loop below.
    //
  } else {
    ChildHandleList = NULL;
  }

  if (Mode == TestModeList) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_HEADER), gShellDriver1HiiHandle);
  }
  for (DriverHandleListLoop = 0
    ;  DriverHandleListLoop < DriverHandleListCount
    ;  DriverHandleListLoop++
    ){
    if (Mode == TestModeList) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER), gShellDriver1HiiHandle, ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]));
    }
    if (ControllerHandle == NULL) {
      PARSE_HANDLE_DATABASE_DEVICES(DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);
    } 
    if (ControllerHandleListCount == 0) {
      if (Mode == TestModeList) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES), gShellDriver1HiiHandle);
      }
    } else {
      if (Mode == TestModeList) {
        ShellPrintEx(-1, -1, L"\r\n");
      }
      for (ControllerHandleListLoop = 0
        ;  ControllerHandleListLoop < ControllerHandleListCount
        ;  ControllerHandleListLoop++
        ){
        if (AllChilds) {
          ASSERT(ChildHandleList == NULL);
          PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(
            DriverHandleList[DriverHandleListLoop], 
            ControllerHandleList[ControllerHandleListLoop],
            &ChildHandleListCount,
            &ChildHandleList);
        }
        for (ChildHandleListLoop = 0
          ;  (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)
          ;  ChildHandleListLoop++
          ){
          Found = FALSE;
          if (Mode != TestModeList) {
            if (Lang == NULL || Lang[2] == '-') {
              //
              // Get the protocol pointer and call the function
              //
              Status = gBS->OpenProtocol(
                DriverHandleList[DriverHandleListLoop],
                &gEfiDriverDiagnostics2ProtocolGuid,
                (VOID**)&DriverDiagnostics2,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL);
              if (!EFI_ERROR(Status)) {
                if (Lang == NULL) {
                  Language = AllocateZeroPool(AsciiStrSize(DriverDiagnostics2->SupportedLanguages));
                  if (Language == NULL) {
                    return (EFI_OUT_OF_RESOURCES);
                  }
                  AsciiStrCpy(Language, DriverDiagnostics2->SupportedLanguages);
                  TempChar = AsciiStrStr(Language, ";");
                  if (TempChar != NULL){
                    *TempChar = CHAR_NULL;
                  }
                } else {
                  Language = AllocateZeroPool(AsciiStrSize(Lang));
                  if (Language == NULL) {
                    return (EFI_OUT_OF_RESOURCES);
                  }
                  AsciiStrCpy(Language, Lang);
                }
                Found = TRUE;
                Status = DriverDiagnostics2->RunDiagnostics(
                  DriverDiagnostics2,
                  ControllerHandleList[ControllerHandleListLoop],
                  ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
                  (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
                  Language,
                  &ErrorType,
                  &OutBufferSize,
                  &OutBuffer);
                FreePool(Language);
              }
            } 
            if (!Found && (Lang == NULL||(Lang!=NULL&&(Lang[2]!='-')))){
              Status = gBS->OpenProtocol(
                DriverHandleList[DriverHandleListLoop],
                &gEfiDriverDiagnosticsProtocolGuid,
                (VOID**)&DriverDiagnostics,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL);
              if (!EFI_ERROR(Status)) {
                if (Lang == NULL) {
                  Language = AllocateZeroPool(AsciiStrSize(DriverDiagnostics2->SupportedLanguages));
                  if (Language == NULL) {
                    return (EFI_OUT_OF_RESOURCES);
                  }
                  AsciiStrCpy(Language, DriverDiagnostics2->SupportedLanguages);
                  TempChar = AsciiStrStr(Language, ";");
                  if (TempChar != NULL){
                    *TempChar = CHAR_NULL;
                  }
                } else {
                  Language = AllocateZeroPool(AsciiStrSize(Lang));
                  if (Language == NULL) {
                    return (EFI_OUT_OF_RESOURCES);
                  }
                  AsciiStrCpy(Language, Lang);
                }
                Status = DriverDiagnostics->RunDiagnostics(
                  DriverDiagnostics,
                  ControllerHandleList[ControllerHandleListLoop],
                  ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
                  (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
                  Language,
                  &ErrorType,
                  &OutBufferSize,
                  &OutBuffer);
                FreePool(Language);
              }
            }
            if (EFI_ERROR(Status)) {
              Status2 = Status;
            }
            HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
            HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
            ShellPrintHiiEx(
              -1,
              -1,
              NULL,
              STRING_TOKEN (STR_3P_RESULT),
              gShellDriver1HiiHandle,
              L"DrvDiag",
              HandleIndex1,
              HandleIndex2,
              ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop]),
              Status);
            if (OutBuffer!=NULL) {
              FreePool(OutBuffer);
              OutBuffer = NULL;
            }
            if (ErrorType!=NULL) {
              FreePool(ErrorType);
              ErrorType = NULL;
            }
          } else {
            HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
            HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
            //
            // Print out the information that this set can be tested
            //
            ShellPrintHiiEx(
              -1,
              -1,
              NULL,
              STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),
              gShellDriver1HiiHandle,
              HandleIndex1,
              HandleIndex2,
              ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop])
           );
          }

          //
          // If we are doing a single pass with NULL child jump out after a single loop
          //
          if (ChildHandleList == NULL) {
            break;
          }
        }
        if (AllChilds) {
          SHELL_FREE_NON_NULL(ChildHandleList);
          ChildHandleList       = NULL;
          ChildHandleListCount  = 0;
        }
      }
      if (ControllerHandle == NULL) {
        SHELL_FREE_NON_NULL(ControllerHandleList);
        ControllerHandleList      = NULL;
        ControllerHandleListCount = 0;
      }
      }
  }

  if (DriverHandleList != NULL) {
    FreePool(DriverHandleList);
  }
  if (ControllerHandleList != NULL) {
    FreePool(ControllerHandleList);
  }
  if (ChildHandleList != NULL) {
    FreePool(ChildHandleList);
  }
  return (Status2);
}
Exemplo n.º 25
0
char*
_plstrcpy(char* dst, const char* src) {
	return AsciiStrCpy(dst, src);
}
Exemplo n.º 26
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;
  AsciiStrCpy ((CHAR8 *) Node + sizeof (ISCSI_DEVICE_PATH), ConfigNvData->TargetName);

  *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;

  return EFI_SUCCESS;
}
Exemplo n.º 27
0
/**
  Get the name of a driver by it's handle.

  If a name is found the memory must be callee freed.

  @param[in] TheHandle    The driver's handle.
  @param[in] Language     The language to use.
  @param[in] NameFound    Upon a successful return the name found.

  @retval EFI_SUCCESS     The name was found.
**/
EFI_STATUS
EFIAPI
GetDriverName (
    IN EFI_HANDLE   TheHandle,
    IN CONST CHAR8  *Language,
    IN CHAR16       **NameFound
)
{
    CHAR8                             *Lang;
    CHAR8                             *TempChar;
    EFI_STATUS                        Status;
    EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
    CHAR16                            *NameToReturn;
    //
    // Go through those handles until we get one that passes for GetComponentName
    //
    Status = gBS->OpenProtocol(
                 TheHandle,
                 &gEfiComponentName2ProtocolGuid,
                 (VOID**)&CompName2,
                 gImageHandle,
                 NULL,
                 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    if (EFI_ERROR(Status)) {
        Status = gBS->OpenProtocol(
                     TheHandle,
                     &gEfiComponentNameProtocolGuid,
                     (VOID**)&CompName2,
                     gImageHandle,
                     NULL,
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    }

    if (EFI_ERROR(Status)) {
        return (EFI_NOT_FOUND);
    }
    if (Language == NULL) {
        Lang = AllocateZeroPool(AsciiStrSize(CompName2->SupportedLanguages));
        if (Lang == NULL) {
            return (EFI_OUT_OF_RESOURCES);
        }
        AsciiStrCpy(Lang, CompName2->SupportedLanguages);
        TempChar = AsciiStrStr(Lang, ";");
        if (TempChar != NULL) {
            *TempChar = CHAR_NULL;
        }
    } else {
        Lang = AllocateZeroPool(AsciiStrSize(Language));
        if (Lang == NULL) {
            return (EFI_OUT_OF_RESOURCES);
        }
        AsciiStrCpy(Lang, Language);
    }
    Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
    FreePool(Lang);

    if (!EFI_ERROR(Status) && NameToReturn != NULL) {
        *NameFound = NULL;
        StrnCatGrow(NameFound, NULL, NameToReturn, 0);
    }
    return (Status);
}
Exemplo n.º 28
0
/**
  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 since it's longer than 64 significant characters.
  @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) { //Slice - there should be a way to add a string if not exists
    return EFI_NOT_FOUND;
  }

  InputStrLen = AsciiStrLen(String);

  //
  // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string
  //
  if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {
    if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {
      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) {
        AsciiStrCpy(StrStart, String);
        EfiReleaseLock (&Private->DataLock);
        return EFI_SUCCESS;
      }

      //
      // 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;
      InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link);

      //
      // Remove old record
      //
      RemoveEntryList(Link);
      FreePool(SmbiosEntry);
      EfiReleaseLock (&Private->DataLock);
      return EFI_SUCCESS;
    }
  }

  EfiReleaseLock (&Private->DataLock);
  return EFI_INVALID_PARAMETER;
}
Exemplo n.º 29
0
/**
  Convert the input ascii string into GUID value.

  @param Str             Ascii GUID string to be converted.
  @param Guid            Pointer to the converted GUID value.

  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
  @retval EFI_NOT_FOUND         The input ascii string is not a valid GUID format string.
  @retval EFI_SUCCESS           GUID value is got.

**/
EFI_STATUS
UpdateStringToGuid (
  IN      UINT8                         *Str,
  IN OUT  EFI_GUID                      *Guid
  )
{
  UINT8                                 *PtrBuffer;
  UINT8                                 *PtrPosition;
  UINT8                                 *Buffer;
  UINTN                                 Data;
  UINTN                                 StrLen;
  UINTN                                 Index;
  UINT8                                 Digits[3];

  StrLen          = AsciiStrLen  ((CONST CHAR8 *) Str);
  Buffer          = AllocatePool (StrLen + 1);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  AsciiStrCpy ((CHAR8 *)Buffer, (CHAR8 *)Str);

  //
  // Data1
  //
  PtrBuffer       = Buffer;
  PtrPosition     = PtrBuffer;
  while (*PtrBuffer != '\0') {
    if (*PtrBuffer == '-') {
      break;
    }
    PtrBuffer++;
  }
  if (*PtrBuffer == '\0') {
    FreePool (Buffer);
    return EFI_NOT_FOUND;
  }

  *PtrBuffer      = '\0';
  Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
  Guid->Data1     = (UINT32)Data;

  //
  // Data2
  //
  PtrBuffer++;
  PtrPosition     = PtrBuffer;
  while (*PtrBuffer != '\0') {
    if (*PtrBuffer == '-') {
      break;
    }
    PtrBuffer++;
  }
  if (*PtrBuffer == '\0') {
    FreePool (Buffer);
    return EFI_NOT_FOUND;
  }
  *PtrBuffer      = '\0';
  Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
  Guid->Data2     = (UINT16)Data;

  //
  // Data3
  //
  PtrBuffer++;
  PtrPosition     = PtrBuffer;
  while (*PtrBuffer != '\0') {
    if (*PtrBuffer == '-') {
      break;
    }
    PtrBuffer++;
  }
  if (*PtrBuffer == '\0') {
    FreePool (Buffer);
    return EFI_NOT_FOUND;
  }
  *PtrBuffer      = '\0';
  Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
  Guid->Data3     = (UINT16)Data;

  //
  // Data4[0..1]
  //
  for ( Index = 0 ; Index < 2 ; Index++) {
    PtrBuffer++;
    if ((*PtrBuffer == '\0') || ( *(PtrBuffer + 1) == '\0')) {
      FreePool (Buffer);
      return EFI_NOT_FOUND;
    }
    Digits[0]     = *PtrBuffer;
    PtrBuffer++;
    Digits[1]     = *PtrBuffer;
    Digits[2]     = '\0';
    Data          = AsciiStrHexToUintn ((CONST CHAR8 *) Digits);
    Guid->Data4[Index] = (UINT8)Data;
  }

  //
  // skip the '-'
  //
  PtrBuffer++;
  if ((*PtrBuffer != '-' ) || ( *PtrBuffer == '\0')) {
    return EFI_NOT_FOUND;
  }

  //
  // Data4[2..7]
  //
  for ( ; Index < 8; Index++) {
    PtrBuffer++;
    if ((*PtrBuffer == '\0') || ( *(PtrBuffer + 1) == '\0')) {
      FreePool (Buffer);
      return EFI_NOT_FOUND;
    }
    Digits[0]     = *PtrBuffer;
    PtrBuffer++;
    Digits[1]     = *PtrBuffer;
    Digits[2]     = '\0';
    Data          = AsciiStrHexToUintn ((CONST CHAR8 *) Digits);
    Guid->Data4[Index] = (UINT8)Data;
  }

  FreePool (Buffer);

  return EFI_SUCCESS;
}