Exemplo n.º 1
0
UINTN
Aprint (
  IN CONST CHAR8  *Format,
  ...
  )
/*++

Routine Description:

  Print function for a maximum of EFI_DRIVER_LIB_MAX_PRINT_BUFFER ascii 
  characters.

Arguments:

  Format - Ascii format string see file header for more details.

  ...    - Vararg list consumed by processing Format.

Returns: 

  Number of characters printed.

--*/
{
  UINTN   Return;
  VA_LIST Marker;
  UINTN   Index;
  UINTN   MaxIndex;
  CHAR16  Buffer[EFI_DRIVER_LIB_MAX_PRINT_BUFFER];
  CHAR16  UnicodeFormat[EFI_DRIVER_LIB_MAX_PRINT_BUFFER];

  MaxIndex = EfiAsciiStrLen ((CHAR8 *) Format);
  if (MaxIndex >= EFI_DRIVER_LIB_MAX_PRINT_BUFFER) {
    //
    // Format string was too long for use to process.
    //
    return 0;
  }

  for (Index = 0; Index < EFI_DRIVER_LIB_MAX_PRINT_BUFFER; Index++) {
    UnicodeFormat[Index] = (CHAR16) Format[Index];
  }

  VA_START (Marker, Format);
  Return = VSPrint (Buffer, sizeof (Buffer), UnicodeFormat, Marker);
  VA_END (Marker);

  //
  // Need to convert to Unicode to do an OutputString
  //

  if (gST->ConOut != NULL) {
    //
    // To be extra safe make sure ConOut has been initialized
    //
    gST->ConOut->OutputString (gST->ConOut, Buffer);
  }

  return Return;
}
Exemplo n.º 2
0
VOID
EfiAsciiStrnCpy (
  OUT CHAR8    *Dst,
  IN  CHAR8    *Src,
  IN  UINTN    Length
  )
/*++

Routine Description:
  Copy the Ascii string from source to destination

Arguments:
  Dst              Destination string
  Src              Source string
  Length           Length of destination string

Returns:

--*/
{
  UINTN Index;
  UINTN SrcLen;

  SrcLen = EfiAsciiStrLen (Src);

  Index = 0;
  while (Index < Length && Index < SrcLen) {
    Dst[Index] = Src[Index];
    Index++;
  }
  for (Index = SrcLen; Index < Length; Index++) {
    Dst[Index] = 0;
  }
}
Exemplo n.º 3
0
BOOLEAN
ReportStatusCodeExtractAssertInfo (
    IN EFI_STATUS_CODE_TYPE     CodeType,
    IN EFI_STATUS_CODE_VALUE    Value,
    IN EFI_STATUS_CODE_DATA     *Data,
    OUT CHAR8                   **Filename,
    OUT CHAR8                   **Description,
    OUT UINT32                  *LineNumber
)
/*++

Routine Description:

  Extract assert information from status code data.

Arguments:

  CodeType    - Code type
  Value       - Code value
  Data        - Optional data associated with this status code.
  Filename    - Filename extracted from Data
  Description - Description extracted from Data
  LineNumber  - Line number extracted from Data

Returns:

  TRUE      - Successfully extracted

  FALSE     - Extraction failed

--*/
{
    EFI_DEBUG_ASSERT_DATA   *AssertData;

    if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
            ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)) {
        //
        // Assume if we have an uncontained unrecoverable error that the data hub
        // may not work. So we will print out data here. If we had an IPMI controller,
        // or error log we could wack the hardware here.
        //
        if ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE && (Data != NULL)) {
            //
            // ASSERT (Expresion) -
            // ExtendedData == FileName
            // Instance     == Line Nuber
            // NULL         == String of Expresion
            //
            AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
            *Filename = (CHAR8 *)(AssertData + 1);
            *Description = *Filename + EfiAsciiStrLen (*Filename) + 1;
            *LineNumber = AssertData->LineNumber;
            return TRUE;
        }
    }
    return FALSE;
}
Exemplo n.º 4
0
UINTN
EfiAsciiStrSize (
  IN CHAR8   *String
  )
/*++

Routine Description:
  Return the number bytes in the Ascii String. This is not the same as
  the length of the string in characters. The string size includes the NULL

Arguments:
  String - String to process

Returns:
  Number of bytes in String

--*/
{
  return (EfiAsciiStrLen (String) + 1);
}
Exemplo n.º 5
0
VOID
EfiAsciiStrCat (
  IN CHAR8   *Destination,
  IN CHAR8   *Source
  )
/*++

Routine Description:
  Concatinate Source on the end of Destination

Arguments:
  Destination - String to added to the end of.
  Source      - String to concatinate.

Returns:
  NONE

--*/
{   
  EfiAsciiStrCpy (Destination + EfiAsciiStrLen (Destination), Source);
}
Exemplo n.º 6
0
STATIC
VOID
IScsiFillNICAndTargetSections (
  IN     EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER  *Table,
  IN OUT UINT8                                      **Heap,
  IN     UINTN                                      HandleCount,
  IN     EFI_HANDLE                                 *Handles
  )
/*++

Routine Description:

  Fill the NIC and target sections in iSCSI Boot Firmware Table.

Arguments:

  Table       - The buffer of the ACPI table.
  Heap        - The heap buffer used to store the variable length parameters such as iSCSI name.
  HandleCount - The number of handles having iSCSI private protocol installed.
  Handles     - The handle buffer.

Returns:

  None.

--*/
{
  EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE  *Control;
  EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE      *Nic;
  EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE   *Target;
  ISCSI_DRIVER_DATA                                     *DriverData;
  ISCSI_SESSION_CONFIG_DATA                             *SessionConfigData;
  ISCSI_CHAP_AUTH_CONFIG_NVDATA                         *AuthConfig;
  UINT16                                                *SectionOffset;
  UINTN                                                 Index;
  UINT16                                                Length;
  EFI_MAC_ADDRESS                                       *Mac;
  ISCSI_PRIVATE_PROTOCOL                                *IScsiIdentifier;
  EFI_STATUS                                            Status;

  //
  // Get the offset of the first Nic and Target section.
  //
  Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
  Nic     = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +
          Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));
  Target  = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
          IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));

  SectionOffset = &Control->NIC0Offset;

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (Handles[Index], &mIScsiPrivateGuid, &IScsiIdentifier);
    if (EFI_ERROR (Status)) {
      ASSERT (FALSE);
      return ;
    }

    DriverData        = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
    SessionConfigData = &DriverData->Session.ConfigData;
    AuthConfig        = &DriverData->Session.AuthData.AuthConfig;

    //
    // Fill the Nic section.
    //
    NetZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));

    Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;
    Nic->Header.Version     = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;
    Nic->Header.Length      = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);
    Nic->Header.Index       = (UINT8) Index;
    Nic->Header.Flags       = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |
                            EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |
                            EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;

    //
    // Get the subnet mask prefix length.
    //
    Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);

    if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {
      Nic->Origin = IpPrefixOriginDhcp;
    } else {
      Nic->Origin = IpPrefixOriginManual;
    }
    //
    // Map the various v4 addresses into v6 addresses.
    //
    IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);
    IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);
    IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);
    IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);
    IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);

    Mac = IScsiGetMacAddress (DriverData->Controller);
    NetCopyMem (Nic->Mac, Mac, sizeof (Nic->Mac));

    //
    // Get the PCI location of the Nic.
    //
    Nic->PciLocation  = IScsiGetNICPciLocation (DriverData->Controller);

    *SectionOffset    = (UINT16) ((UINTN) Nic - (UINTN) Table);
    SectionOffset++;

    //
    // Fill the Target section.
    //
    NetZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));

    Target->Header.StructureId  = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;
    Target->Header.Version      = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;
    Target->Header.Length       = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);
    Target->Header.Index        = (UINT8) Index;
    Target->Header.Flags        = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;
    Target->Port                = SessionConfigData->NvData.TargetPort;
    Target->CHAPType            = AuthConfig->CHAPType;
    Target->NicIndex            = (UINT8) Index;

    IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);
    NetCopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));

    //
    // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.
    //
    Length = (UINT16) EfiAsciiStrLen (SessionConfigData->NvData.TargetName);
    IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);

    Target->IScsiNameLength = Length;
    Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);

    if (Target->CHAPType != ISCSI_CHAP_NONE) {
      //
      // CHAP Name
      //
      Length = (UINT16) EfiAsciiStrLen (AuthConfig->CHAPName);
      IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);
      Target->CHAPNameLength  = Length;
      Target->CHAPNameOffset  = (UINT16) ((UINTN) *Heap - (UINTN) Table);

      //
      // CHAP Secret
      //
      Length = (UINT16) EfiAsciiStrLen (AuthConfig->CHAPSecret);
      IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);
      Target->CHAPSecretLength  = Length;
      Target->CHAPSecretOffset  = (UINT16) ((UINTN) *Heap - (UINTN) Table);

      if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {
        //
        // Reverse CHAP Name
        //
        Length = (UINT16) EfiAsciiStrLen (AuthConfig->ReverseCHAPName);
        IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);
        Target->ReverseCHAPNameLength = Length;
        Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);

        //
        // Reverse CHAP Secret
        //
        Length = (UINT16) EfiAsciiStrLen (AuthConfig->ReverseCHAPSecret);
        IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);
        Target->ReverseCHAPSecretLength = Length;
        Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
      }
    }

    *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);
    SectionOffset++;

    //
    // Advance to the next NIC/Target pair
    //
    Nic    = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +
           IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));
    Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
           IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
  }
}
Exemplo n.º 7
0
VOID
InitializeLanguage (
  BOOLEAN LangCodesSettingRequired
  )
/*++

Routine Description:
  Determine the current language that will be used
  based on language related EFI Variables

Arguments:
  LangCodesSettingRequired - If required to set LangCode variable

Returns:

--*/
{
  EFI_STATUS  Status;
  UINTN       Size;
  CHAR8       Lang[RFC_3066_ENTRY_SIZE];
  CHAR8       CurrentLang[RFC_3066_ENTRY_SIZE];
  CHAR8       *LangCodes;
  CHAR8       *LangStrings;
#ifdef LANG_SUPPORT
  CHAR8       *OldLangCodes;
  CHAR8       OldLang[ISO_639_2_ENTRY_SIZE];
#endif

  ExportFonts ();

  //
  // Collect the languages from what our current Language support is based on our VFR
  //
  LangCodes = GetSupportedLanguages (gStringPackHandle);
  ASSERT (LangCodes != NULL);

  if (LangCodesSettingRequired) {
    Status = gRT->SetVariable (
                    L"PlatformLangCodes",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    EfiAsciiStrSize (LangCodes),
                    LangCodes
                    );

#ifdef LANG_SUPPORT
    //
    // Set UEFI deprecated variable "LangCodes" for backwards compatibility
    //
    OldLangCodes = Rfc3066ToIso639 (LangCodes);
    Status = gRT->SetVariable (
                    L"LangCodes",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    EfiAsciiStrLen (OldLangCodes),
                    OldLangCodes
                    );
    gBS->FreePool (OldLangCodes);
#endif
  }

  //
  // Find current LangCode from Lang NV Variable
  //
  Size = RFC_3066_ENTRY_SIZE;
  Status = gRT->GetVariable (
                  L"PlatformLang",
                  &gEfiGlobalVariableGuid,
                  NULL,
                  &Size,
                  CurrentLang
                  );

  if (!EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;

    LangStrings = LangCodes;
    while (*LangStrings != 0) {
      GetNextLanguage (&LangStrings, Lang);

      if (EfiAsciiStrCmp (Lang, CurrentLang) == 0) {
        Status = EFI_SUCCESS;
        break;
      }
    }
  }

  //
  // If we cannot get language code from variable,
  // or LangCode cannot be found from language table,
  // set the first language in language table to variable.
  //
  if (EFI_ERROR (Status)) {
    LangStrings = LangCodes;
    GetNextLanguage (&LangStrings, Lang);
    Status = gRT->SetVariable (
                    L"PlatformLang",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    EfiAsciiStrSize (mDefaultLangCode),
                    Lang
                    );
#ifdef LANG_SUPPORT
    //
    // Set UEFI deprecated variable "Lang" for backwards compatibility
    //
    Status = ConvertRfc3066LanguageToIso639Language (mDefaultLangCode, OldLang);
    if (!EFI_ERROR (Status)) {
      Status = gRT->SetVariable (
                      L"Lang",
                      &gEfiGlobalVariableGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                      ISO_639_2_ENTRY_SIZE,
                      OldLang
                      );
    }
#endif
  }

  if (LangCodes != NULL) {
    gBS->FreePool (LangCodes);
  }
}
Exemplo n.º 8
0
EFI_STATUS
PxeBcTftpGetFileSize (
  IN PXEBC_PRIVATE_DATA         *Private,
  IN EFI_MTFTP4_CONFIG_DATA     *Config,
  IN UINT8                      *Filename,
  IN UINTN                      *BlockSize,
  IN OUT UINT64                 *BufferSize
  )
/*++

Routine Description:

  This function is to get size of a file by Tftp.

Arguments:

  Private     - Pointer to PxeBc private data
  Config      - Pointer to Mtftp configuration data
  Filename    - Pointer to file name
  BlockSize   - Pointer to block size
  BufferSize  - Pointer to buffer size

Returns:

  EFI_SUCCESS
  EFI_NOT_FOUND
  EFI_DEVICE_ERROR
  
--*/
{
  EFI_MTFTP4_PROTOCOL *Mtftp4;
  EFI_MTFTP4_OPTION   ReqOpt[2];
  EFI_MTFTP4_PACKET   *Packet;
  EFI_MTFTP4_OPTION   *Option;
  UINT32              PktLen;
  UINT8               OptBuf[128];
  UINT32              OptCnt;
  EFI_STATUS          Status;

  *BufferSize               = 0;
  Status                    = EFI_DEVICE_ERROR;
  Mtftp4                    = Private->Mtftp4;
  Packet                    = NULL;
  Option                    = NULL;
  PktLen                    = 0;
  OptCnt                    = 1;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp4->Configure (Mtftp4, Config);
  if (EFI_ERROR (Status)) {

    return Status;
  }

  ReqOpt[0].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
  UtoA10 (0, OptBuf);
  ReqOpt[0].ValueStr = OptBuf;

  if (BlockSize != NULL) {
    ReqOpt[1].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[1].ValueStr  = ReqOpt[0].ValueStr + EfiAsciiStrLen (ReqOpt[0].ValueStr) + 1;
    UtoA10 (*BlockSize, ReqOpt[1].ValueStr);
    OptCnt++;
  }

  Status = Mtftp4->GetInfo (
                    Mtftp4,
                    FALSE,
                    Filename,
                    NULL,
                    (UINT8) OptCnt,
                    ReqOpt,
                    &PktLen,
                    &Packet
                    );

  if (EFI_ERROR (Status)) {

    goto ON_ERROR;
  }

  OptCnt = 0;

  Status = Mtftp4->ParseOptions (
                    Mtftp4,
                    PktLen,
                    Packet,
                    (UINT32 *) &OptCnt,
                    &Option
                    );

  if (EFI_ERROR (Status)) {

    goto ON_ERROR;
  }

  Status = EFI_NOT_FOUND;

  while (OptCnt != 0) {

    if (!EfiAsciiStrnCmp (Option[OptCnt - 1].OptionStr, "tsize", 5)) {

      *BufferSize = AtoU64 (Option[OptCnt - 1].ValueStr);
      Status      = EFI_SUCCESS;
    }

    OptCnt--;
  }

  NetFreePool (Option);

ON_ERROR:

  if (Packet != NULL) {
    NetFreePool (Packet);
  }

  Mtftp4->Configure (Mtftp4, NULL);

  return Status;
}
Exemplo n.º 9
0
UINTN
ErrorPrint (
  IN CONST CHAR16 *ErrorString,
  IN CONST CHAR8  *Format,
  ...
  )
/*++

Routine Description:

  Print function for a maximum of EFI_DRIVER_LIB_MAX_PRINT_BUFFER ascii 
  characters.

Arguments:

  ErrorString - String of error infomation.

  Format      - Ascii format string see file header for more details.

  ...         - Vararg list consumed by processing Format.

Returns: 

  Number of characters printed.

--*/
{
  UINTN   Return;
  VA_LIST Marker;
  UINTN   Index;
  UINTN   MaxIndex;
  CHAR16  Buffer[EFI_DRIVER_LIB_MAX_PRINT_BUFFER];
  CHAR16  UnicodeFormat[EFI_DRIVER_LIB_MAX_PRINT_BUFFER];

  MaxIndex = EfiAsciiStrLen ((CHAR8 *) Format);
  if (MaxIndex >= EFI_DRIVER_LIB_MAX_PRINT_BUFFER) {
    //
    // Format string was too long for use to process.
    //
    return 0;
  }

  if (ErrorString != '\0') {
    if (gST->StdErr != NULL) {
      //
      // To be extra safe make sure StdErr has been initialized
      //
      gST->StdErr->SetAttribute (gST->StdErr, EFI_TEXT_ATTR (EFI_RED, EFI_BLACK));
      gST->StdErr->OutputString (gST->StdErr, (CHAR16 *) ErrorString);
      gST->StdErr->SetAttribute (gST->StdErr, EFI_TEXT_ATTR (EFI_WHITE, EFI_BLACK));
    }
  }

  for (Index = 0; Index < MaxIndex; Index++) {
    UnicodeFormat[Index] = (CHAR16) Format[Index];
  }

  UnicodeFormat[Index] = 0;

  VA_START (Marker, Format);
  Return = VSPrint (Buffer, sizeof (Buffer), UnicodeFormat, Marker);
  VA_END (Marker);

  //
  // Need to convert to Unicode to do an OutputString
  //

  if (gST->StdErr != NULL) {
    //
    // To be extra safe make sure StdErr has been initialized
    //
    gST->StdErr->OutputString (gST->StdErr, Buffer);
  }

  return Return;
}
Exemplo n.º 10
0
EFI_STATUS
EfiLibAddUnicodeString (
  IN      CHAR8                     *Language,
  IN      CHAR8                     *SupportedLanguages,
  IN OUT  EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,
  IN      CHAR16                    *UnicodeString
  )
/*++

Routine Description:

  Add an translation to the dictionary if this language if supported.
  
Arguments:

  Language              - The name of language to translate to
  SupportedLanguages    - Supported languages set
  UnicodeStringTable    - Translation dictionary
  UnicodeString         - The corresponding string for the language to be translated to

Returns: 

  EFI_INVALID_PARAMETER - Invalid parameter
  EFI_UNSUPPORTED       - System not supported this language
  EFI_ALREADY_STARTED   - Already has a translation item of this language
  EFI_OUT_OF_RESOURCES  - No enough buffer to be allocated
  EFI_SUCCESS           - String successfully translated

--*/
{
  UINTN                     NumberOfEntries;
  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;
  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;
  UINTN                     UnicodeStringLength;

  //
  // Make sure the parameter are valid
  //
  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If there are no supported languages, then a Unicode String can not be added
  //
  if (SupportedLanguages == NULL) {
    return EFI_UNSUPPORTED;
  }

  //
  // If the Unicode String is empty, then a Unicode String can not be added
  //
  if (UnicodeString[0] == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Make sure Language is a member of SupportedLanguages
  //
  while (*SupportedLanguages != 0) {
    if (EfiLibCompareLanguage (Language, SupportedLanguages)) {

      //
      // Determine the size of the Unicode String Table by looking for a NULL Language entry
      //
      NumberOfEntries = 0;
      if (*UnicodeStringTable != NULL) {
        OldUnicodeStringTable = *UnicodeStringTable;
        while (OldUnicodeStringTable->Language != NULL) {
          if (EfiLibCompareLanguage (Language, OldUnicodeStringTable->Language)) {
            return EFI_ALREADY_STARTED;
          }

          OldUnicodeStringTable++;
          NumberOfEntries++;
        }
      }

      //
      // Allocate space for a new Unicode String Table.  It must hold the current number of
      // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
      // marker
      //
      NewUnicodeStringTable = EfiLibAllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));
      if (NewUnicodeStringTable == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // If the current Unicode String Table contains any entries, then copy them to the
      // newly allocated Unicode String Table.
      //
      if (*UnicodeStringTable != NULL) {
        EfiCopyMem (
          NewUnicodeStringTable,
          *UnicodeStringTable,
          NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)
          );
      }

      //
      // Allocate space for a copy of the Language specifier
      //
      NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrLen(Language) + 1, Language);
      if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {
        gBS->FreePool (NewUnicodeStringTable);
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Compute the length of the Unicode String
      //
      for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)
        ;

      //
      // Allocate space for a copy of the Unicode String
      //
      NewUnicodeStringTable[NumberOfEntries].UnicodeString = EfiLibAllocateCopyPool (
                                                              (UnicodeStringLength + 1) * sizeof (CHAR16),
                                                              UnicodeString
                                                              );
      if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {
        gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);
        gBS->FreePool (NewUnicodeStringTable);
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Mark the end of the Unicode String Table
      //
      NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;
      NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;

      //
      // Free the old Unicode String Table
      //
      if (*UnicodeStringTable != NULL) {
        gBS->FreePool (*UnicodeStringTable);
      }

      //
      // Point UnicodeStringTable at the newly allocated Unicode String Table
      //
      *UnicodeStringTable = NewUnicodeStringTable;

      return EFI_SUCCESS;
    }

    SupportedLanguages = NextSupportedLanguage(SupportedLanguages);
  }

  return EFI_UNSUPPORTED;
}
Exemplo n.º 11
0
EFI_STATUS
EfiDebugVPrintWorker (
    IN  UINTN                   ErrorLevel,
    IN  CHAR8                   *Format,
    IN  VA_LIST                 Marker,
    IN  UINTN                   BufferSize,
    IN OUT VOID                 *Buffer
)
/*++

Routine Description:

  Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT
  information. If Error Logging hub is not loaded do nothing.

  The Format string might be truncated to fit into the status code struture
  which has the max size of EFI_STATUS_CODE_DATA_MAX_SIZE.

  We use UINT64 buffers due to IPF alignment concerns.

Arguments:

  ErrorLevel - If error level is set do the debug print.

  Format     - String to use for the print, followed by Print arguments.

  Marker     - VarArgs

  BufferSize - Size of Buffer.

  Buffer     - Caller allocated buffer, contains ReportStatusCode extended data

Returns:

  Status code

  EFI_SUCCESS             - Successfully printed

--*/
{
    UINTN                   Index;
    UINTN                   FormatStrLen;
    UINTN                   RemainingStrLen;
    UINT64                  *Ptr;
    EFI_DEBUG_INFO          *EfiDebug;


    //
    // Build the type specific EFI_STATUS_CODE_DATA in order
    //

    //
    // Fill in EFI_STATUS_CODE_DATA to Buffer.
    //
    EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData (
                   (UINT16)BufferSize,
                   &gEfiStatusCodeDataTypeDebugGuid,
                   Buffer
               );

    //
    // Then EFI_DEBUG_INFO
    //
    EfiDebug->ErrorLevel = (UINT32)ErrorLevel;

    //
    // 12 * sizeof (UINT64) byte mini Var Arg stack.
    // That is followed by the format string.
    //
    for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) {
        *Ptr = VA_ARG (Marker, UINT64);
    }

    //
    // Place Ascii Format string at the end
    // Truncate it to fit into the status code structure
    //
    FormatStrLen    = EfiAsciiStrLen (Format);
    RemainingStrLen = EFI_STATUS_CODE_DATA_MAX_SIZE
                      - sizeof (EFI_STATUS_CODE_DATA)
                      - sizeof (EFI_DEBUG_INFO)
                      - 12 * sizeof (UINT64) - 1;
    if (FormatStrLen > RemainingStrLen) {
        FormatStrLen = RemainingStrLen;
    }
    EfiCommonLibCopyMem (Ptr, Format, FormatStrLen);
    *((CHAR8 *) Ptr + FormatStrLen) = '\0';

    return EFI_SUCCESS;
}
Exemplo n.º 12
0
EFI_STATUS
EfiDebugAssertWorker (
    IN CHAR8                    *Filename,
    IN INTN                     LineNumber,
    IN CHAR8                    *Description,
    IN UINTN                    BufferSize,
    IN OUT VOID                 *Buffer
)
/*++

Routine Description:

  Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT
  information. If Error Logging hub is not loaded DEADLOOP ().

  We use UINT64 buffers due to IPF alignment concerns.

Arguments:

  Filename    - File name of failing routine.

  LineNumber  - Line number of failing ASSERT().

  Description - Description, usually the assertion,

  BufferSize - Size of Buffer.

  Buffer     - Caller allocated buffer, contains ReportStatusCode extendecd data

Returns:

  Status code

  EFI_BUFFER_TOO_SMALL      - Buffer not large enough

  EFI_SUCCESS               - Function successfully done.

--*/
{
    EFI_DEBUG_ASSERT_DATA   *AssertData;
    UINTN                   TotalSize;
    CHAR8                   *EndOfStr;

    //
    // Make sure it will all fit in the passed in buffer
    //
    TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA);
    TotalSize += EfiAsciiStrLen (Filename);
    TotalSize += EfiAsciiStrLen (Description);
    if (TotalSize > BufferSize) {
        return EFI_BUFFER_TOO_SMALL;
    }

    //
    // Fill in EFI_STATUS_CODE_DATA
    //
    AssertData =  (EFI_DEBUG_ASSERT_DATA *)
                  EfiConstructStatusCodeData (
                      (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)),
                      &gEfiStatusCodeDataTypeAssertGuid,
                      Buffer
                  );

    //
    // Fill in EFI_DEBUG_ASSERT_DATA
    //
    AssertData->LineNumber = (UINT32)LineNumber;

    //
    // Copy Ascii FileName including NULL.
    //
    EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename);

    //
    // Copy Ascii Description
    //
    EfiAsciiStrCpy (EndOfStr, Description);
    return EFI_SUCCESS;
}