frontpage.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 915 行 · 第 1/2 页

C
915
字号

  gBS->RaiseTPL (EFI_TPL_DRIVER);
  return Status;
}

EFI_STATUS
GetStringFromToken (
  IN      EFI_GUID                  *ProducerGuid,
  IN      STRING_REF                Token,
  OUT     CHAR16                    **String
  )
/*++

Routine Description:
  
  Acquire the string associated with the ProducerGuid and return it.

Arguments:
  
  ProducerGuid - The Guid to search the HII database for
  Token - The token value of the string to extract
  String - The string that is extracted
  
Returns:

  EFI_SUCCESS - The function returns EFI_SUCCESS always.

--*/
{
  EFI_STATUS      Status;
  UINT16          HandleBufferLength;
  EFI_HII_HANDLE  *HiiHandleBuffer;
  UINTN           StringBufferLength;
  UINTN           NumberOfHiiHandles;
  UINTN           Index;
  UINT16          Length;
  EFI_GUID        HiiGuid;

  //
  // Initialize params.
  //
  HandleBufferLength  = 0;
  HiiHandleBuffer     = NULL;

  //
  // Get all the Hii handles
  //
  Status = BdsLibGetHiiHandles (Hii, &HandleBufferLength, &HiiHandleBuffer);
  ASSERT_EFI_ERROR (Status);

  //
  // Get the Hii Handle that matches the StructureNode->ProducerName
  //
  NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
  for (Index = 0; Index < NumberOfHiiHandles; Index++) {
    Length = 0;
    Status = ExtractDataFromHiiHandle (
              HiiHandleBuffer[Index],
              &Length,
              NULL,
              &HiiGuid
              );
    if (EfiCompareGuid (ProducerGuid, &HiiGuid)) {
      break;
    }
  }
  //
  // Find the string based on the current language
  //
  StringBufferLength  = 0x100;
  *String             = EfiLibAllocateZeroPool (0x100);
  Status = Hii->GetString (
                  Hii,
                  HiiHandleBuffer[Index],
                  Token,
                  FALSE,
                  NULL,
                  &StringBufferLength,
                  *String
                  );

  if (EFI_ERROR (Status)) {
    gBS->FreePool (*String);
    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
  }

  gBS->FreePool (HiiHandleBuffer);
  return EFI_SUCCESS;
}

VOID
ConvertProcessorToString (
  IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,
  OUT CHAR16                            **String
  )
/*++

Routine Description:
  
  Convert Processor Frequency Data to a string

Arguments:
  
  ProcessorFrequency - The frequency data to process
  String - The string that is created
  
Returns:

--*/
{
  CHAR16  *StringBuffer;
  UINTN   Index;
  UINT32  FreqMhz;

  if (ProcessorFrequency->Exponent >= 6) {
    FreqMhz = ProcessorFrequency->Value;
    for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {
      FreqMhz *= 10;
    }
  } else {
    FreqMhz = 0;
  }

  StringBuffer = EfiLibAllocateZeroPool (0x20);
  ASSERT (StringBuffer != NULL);
  Index = EfiValueToString (StringBuffer, FreqMhz / 1000, LEFT_JUSTIFY, 3);
  EfiStrCat (StringBuffer, L".");
  EfiValueToString (StringBuffer + Index + 1, (FreqMhz % 1000) / 10, PREFIX_ZERO, 2);
  EfiStrCat (StringBuffer, L" GHz");

  *String = (CHAR16 *) StringBuffer;

  return ;
}

VOID
ConvertMemorySizeToString (
  IN  UINT32          MemorySize,
  OUT CHAR16          **String
  )
/*++

Routine Description:
  
  Convert Memory Size to a string

Arguments:
  
  MemorySize - The size of the memory to process
  String - The string that is created
  
Returns:

--*/
{
  CHAR16  *StringBuffer;

  StringBuffer = EfiLibAllocateZeroPool (0x20);
  ASSERT (StringBuffer != NULL);
  EfiValueToString (StringBuffer, MemorySize, LEFT_JUSTIFY, 6);
  EfiStrCat (StringBuffer, L" MB RAM");

  *String = (CHAR16 *) StringBuffer;

  return ;
}

VOID
UpdateFrontPageStrings (
  VOID
  )
/*++

Routine Description:
  
  Update the banner information for the Front Page based on DataHub information

Arguments:
  
  None
  
Returns:

--*/
{
  EFI_STATUS                        Status;
  STRING_REF                        TokenToUpdate;
  CHAR16                            *NewString;
  UINT64                            MonotonicCount;
  EFI_DATA_HUB_PROTOCOL             *DataHub;
  EFI_DATA_RECORD_HEADER            *Record;
  EFI_SUBCLASS_TYPE1_HEADER         *DataHeader;
  EFI_MISC_BIOS_VENDOR              *BiosVendor;
  EFI_MISC_SYSTEM_MANUFACTURER      *SystemManufacturer;
  EFI_PROCESSOR_VERSION_DATA        *ProcessorVersion;
  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;
  EFI_MEMORY_ARRAY_START_ADDRESS    *MemoryArray;
  CHAR8                             LangCode[3];
  CHAR16                            Lang[3];
  UINTN                             Size;
  UINTN                             Index;
  BOOLEAN                           Find[5];

  EfiZeroMem (Find, sizeof (Find));

  //
  // Update Front Page strings
  //
  Status = gBS->LocateProtocol (
                  &gEfiDataHubProtocolGuid,
                  NULL,
                  &DataHub
                  );
  ASSERT_EFI_ERROR (Status);

  Size = 3;

  Status = gRT->GetVariable (
                  L"Lang",
                  &gEfiGlobalVariableGuid,
                  NULL,
                  &Size,
                  LangCode
                  );

  for (Index = 0; Index < 3; Index++) {
    Lang[Index] = (CHAR16) LangCode[Index];
  }

  MonotonicCount  = 0;
  Record          = NULL;
  do {
    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
      DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
      if (EfiCompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&
          (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)
          ) {
        BiosVendor = (EFI_MISC_BIOS_VENDOR *) (DataHeader + 1);
        GetStringFromToken (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_BIOS_VERSION;
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
        gBS->FreePool (NewString);
        Find[0] = TRUE;
      }

      if (EfiCompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&
          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)
          ) {
        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER *) (DataHeader + 1);
        GetStringFromToken (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_COMPUTER_MODEL;
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
        gBS->FreePool (NewString);
        Find[1] = TRUE;
      }

      if (EfiCompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&
          (DataHeader->RecordType == ProcessorVersionRecordType)
          ) {
        ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);
        GetStringFromToken (&Record->ProducerName, *ProcessorVersion, &NewString);
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_MODEL;
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
        gBS->FreePool (NewString);
        Find[2] = TRUE;
      }

      if (EfiCompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&
          (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)
          ) {
        ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);
        ConvertProcessorToString (ProcessorFrequency, &NewString);
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_SPEED;
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
        gBS->FreePool (NewString);
        Find[3] = TRUE;
      }

      if (EfiCompareGuid (&Record->DataRecordGuid, &mMemorySubClass) &&
          (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)
          ) {
        MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS *) (DataHeader + 1);
        ConvertMemorySizeToString((UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - 
                                  MemoryArray->MemoryArrayStartAddress + 1), 20)),
                                  &NewString);
        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_MEMORY_SIZE;
        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);
        gBS->FreePool (NewString);
        Find[4] = TRUE;
      }
    }
  } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));

  return ;
}

VOID
PlatformBdsEnterFrontPage (
  IN UINT16                       TimeoutDefault,
  IN BOOLEAN                      ConnectAllHappened
  )
/*++

Routine Description:
  This function is the main entry of the platform setup entry.
  The function will present the main menu of the system setup, 
  this is the platform reference part and can be customize.
  
Arguments:
  TimeoutDefault     - The fault time out value before the system
                       continue to boot.
  ConnectAllHappened - The indicater to check if the connect all have
                       already happended.
  
Returns:
  None

--*/
{
  EFI_STATUS                    Status;
  EFI_HII_UPDATE_DATA           *UpdateData;
  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;

  //
  // Indicate if we need connect all in the platform setup
  //
  if (ConnectAllHappened) {
    gConnectAllHappened = TRUE;
  }
  //
  // Allocate space for creation of Buffer
  //
  UpdateData = EfiLibAllocateZeroPool (0x1000);
  ASSERT (UpdateData != NULL);

  UpdateData->FormSetUpdate       = FALSE;
  UpdateData->FormCallbackHandle  = 0;
  UpdateData->FormUpdate          = FALSE;
  UpdateData->FormTitle           = 0;
  UpdateData->DataCount           = 1;

  //
  // Remove Banner Op-code if any at this label
  //
  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, FALSE, UpdateData);

  //
  // Create Banner Op-code which reflects correct timeout value
  //
  CreateBannerOpCode (
    STRING_TOKEN (STR_TIME_OUT_PROMPT),
    TimeoutDefault,
    (UINT8) EFI_IFR_BANNER_TIMEOUT,
    &UpdateData->Data
    );

  //
  // Add Banner Op-code at this label
  //
  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, TRUE, UpdateData);

  do {

    InitializeFrontPage (TRUE);

    //
    // Update Front Page strings
    //
    UpdateFrontPageStrings ();

    gCallbackKey = 0;
    PERF_START (0, L"BdsTimeOut", L"BDS", 0);
    Status = CallFrontPage ();
    PERF_END (0, L"BdsTimeOut", L"BDS", 0);

    //
    // If gCallbackKey is greater than 1 and less or equal to 5,
    // it will lauch configuration utilities.
    // 2 = set language
    // 3 = boot manager
    // 4 = device manager
    // 5 = boot maintainenance manager
    //
    if ((gCallbackKey > 0x0001) && (gCallbackKey <= 0x0005)) {
      EfiLibReportStatusCode (
        EFI_PROGRESS_CODE,
        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP),
        0,
        &gEfiBdsArchProtocolGuid,
        NULL
        );
    }
    //
    // Based on the key that was set, we can determine what to do
    //
    switch (gCallbackKey) {
    //
    // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
    // describe to their customers in documentation how to find their setup information (namely
    // under the device manager and specific buckets)
    //
    // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
    //
    case 0x0001:
      //
      // User hit continue
      //
      break;

    case 0x0002:
      //
      // User made a language setting change - display front page again
      //
      break;

    case 0x0003:
      //
      // User chose to run the Boot Manager
      //
      CallBootManager ();
      break;

    case 0x0004:
      //
      // Display the Device Manager
      //
      do {
        CallDeviceManager();
      } while (gCallbackKey == 4);
      break;

    case 0x0005:
      //
      // Display the Boot Maintenance Manager
      //
      BdsStartBootMaint ();
      break;
    }

  } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1));
  
  //
  //Will leave browser, check any reset required change is applied? if yes, reset system
  //
  SetupResetReminder ();
  
  //
  // Automatically load current entry
  // Note: The following lines of code only execute when Auto boot
  // takes affect
  //
  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl);
  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?