diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec index 709b2bd33b..c5b2da847c 100644 --- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec +++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec @@ -192,3 +192,22 @@ ## The PCD is used to specify the high PMM (Post Memory Manager) size with bytes above 1MB. # The value should be a multiple of 4KB. gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize|0x400000|UINT32|0x3000000a + + ## The 4 PCDs below are used to specify the video resolution and text mode of text setup. + # To make text setup work in this resolution, PcdVideoHorizontalResolution, PcdVideoVerticalResolution, + # PcdConOutColumn and PcdConOutRow in MdeModulePkg.dec should be created as PcdsDynamic or PcdsDynamicEx + # in platform DSC file. Then BDS setup will update these PCDs defined in MdeModulePkg.dec and reconnect + # console drivers (GraphicsConsole, Terminal, Consplitter) to make the video resolution and text mode work + # for text setup. + + ## The PCD is used to specify the video horizontal resolution of text setup. + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800|UINT32|0x3000000b + + ## The PCD is used to specify the video vertical resolution of text setup. + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600|UINT32|0x3000000c + + ## The PCD is used to specify the console output column of text setup. + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupConOutColumn|80|UINT32|0x3000000d + + ## The PCD is used to specify the console output column of text setup. + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupConOutRow|25|UINT32|0x3000000e \ No newline at end of file diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c index 30c48f48ee..efe881bf2f 100644 --- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c +++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c @@ -654,24 +654,6 @@ BdsLibBootViaBootOption ( } } - // - // Signal the EVT_SIGNAL_READY_TO_BOOT event - // - EfiSignalEventReadyToBoot(); - - // - // Expand USB Class or USB WWID device path node to be full device path of a USB - // device in platform then load the boot file on this full device path and get the - // image handle. - // - ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath); - - // - // Adjust the different type memory page number just before booting - // and save the updated info into the variable for next boot to use - // - BdsSetMemoryTypeInformationVariable (); - // // Set Boot Current // @@ -690,6 +672,24 @@ BdsLibBootViaBootOption ( ); } + // + // Signal the EVT_SIGNAL_READY_TO_BOOT event + // + EfiSignalEventReadyToBoot(); + + // + // Expand USB Class or USB WWID device path node to be full device path of a USB + // device in platform then load the boot file on this full device path and get the + // image handle. + // + ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath); + + // + // Adjust the different type memory page number just before booting + // and save the updated info into the variable for next boot to use + // + BdsSetMemoryTypeInformationVariable (); + // // By expanding the USB Class or WWID device path, the ImageHandle has returnned. // Here get the ImageHandle for the non USB class or WWID device path. diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf index bb9775343f..ed5a240d6a 100644 --- a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf +++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf @@ -177,6 +177,13 @@ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupConOutColumn + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupConOutRow + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile [Depex] TRUE diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c index 8ff5fa0a16..b77e909ad5 100644 --- a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c +++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c @@ -161,6 +161,10 @@ UpdateFileExplorer ( // Here boot from file // BootThisFile (NewFileContext); + // + // Set proper video resolution and text mode for setup. + // + ChangeModeForSetup (); ExitFileExplorer = TRUE; break; diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c index 4cd0691b91..125ba63ea0 100644 --- a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c +++ b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c @@ -939,6 +939,187 @@ ShowProgress ( return EFI_SUCCESS; } +/** + This function will change video resolution and text mode for setup when setup is launched. + + @param None. + + @retval EFI_SUCCESS Mode is changed successfully. + @retval Others Mode failed to changed. + +**/ +EFI_STATUS +EFIAPI +ChangeModeForSetup ( + VOID + ) +{ + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; + UINTN SizeOfInfo; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINT32 MaxGopMode; + UINT32 MaxTextMode; + UINT32 ModeNumber; + UINT32 SetupTextModeColumn; + UINT32 SetupTextModeRow; + UINT32 SetupHorizontalResolution; + UINT32 SetupVerticalResolution; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_STATUS Status; + UINTN Index; + UINTN CurrentColumn; + UINTN CurrentRow; + + Status = gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID**)&GraphicsOutput + ); + if (EFI_ERROR (Status)) { + GraphicsOutput = NULL; + } + + Status = gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiSimpleTextOutProtocolGuid, + (VOID**)&SimpleTextOut + ); + if (EFI_ERROR (Status)) { + SimpleTextOut = NULL; + } + + if ((GraphicsOutput == NULL) && (SimpleTextOut == NULL)) { + return EFI_UNSUPPORTED; + } + + // + // Get user defined text mode for setup. + // + SetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); + SetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); + SetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); + SetupTextModeRow = PcdGet32 (PcdSetupConOutRow); + + MaxGopMode = GraphicsOutput->Mode->MaxMode; + MaxTextMode = SimpleTextOut->Mode->MaxMode; + + // + // 1. If current video resolution is same with setup video resolution, + // video resolution need not be changed. + // 1.1. If current text mode is same with setup text mode, text mode need not be changed. + // 1.2. If current text mode is different with setup text mode, text mode need be changed to setup text mode. + // 2. If current video resolution is different with setup video resolution, we need restart whole console drivers. + // + for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) { + Status = GraphicsOutput->QueryMode ( + GraphicsOutput, + ModeNumber, + &SizeOfInfo, + &Info + ); + if (!EFI_ERROR (Status)) { + if ((Info->HorizontalResolution == SetupHorizontalResolution) && + (Info->VerticalResolution == SetupVerticalResolution)) { + if ((GraphicsOutput->Mode->Info->HorizontalResolution == SetupHorizontalResolution) && + (GraphicsOutput->Mode->Info->VerticalResolution == SetupVerticalResolution)) { + // + // If current video resolution is same with setup video resolution, + // then check if current text mode is same with setup text mode. + // + Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow); + ASSERT_EFI_ERROR (Status); + if (CurrentColumn == SetupTextModeColumn && CurrentRow == SetupTextModeRow) { + // + // Current text mode is same with setup text mode, text mode need not be change. + // + FreePool (Info); + return EFI_SUCCESS; + } else { + // + // Current text mode is different with setup text mode, text mode need be change to new text mode. + // + for (Index = 0; Index < MaxTextMode; Index++) { + Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow); + if (!EFI_ERROR(Status)) { + if ((CurrentColumn == SetupTextModeColumn) && (CurrentRow == SetupTextModeRow)) { + // + // setup text mode is supported, set it. + // + Status = SimpleTextOut->SetMode (SimpleTextOut, Index); + ASSERT_EFI_ERROR (Status); + // + // Update text mode PCD. + // + PcdSet32 (PcdConOutColumn, SetupTextModeColumn); + PcdSet32 (PcdConOutRow, SetupTextModeRow); + FreePool (Info); + return EFI_SUCCESS; + } + } + } + if (Index == MaxTextMode) { + // + // If setup text mode is not supported, return error. + // + FreePool (Info); + return EFI_UNSUPPORTED; + } + } + } else { + FreePool (Info); + // + // If current video resolution is not same with the setup video resolution, set new video resolution. + // In this case, the drivers which produce simple text out need be restarted. + // + Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber); + if (!EFI_ERROR (Status)) { + // + // Set PCD to restart GraphicsConsole and Consplitter to change video resolution + // and produce new text mode based on new resolution. + // + PcdSet32 (PcdVideoHorizontalResolution, SetupHorizontalResolution); + PcdSet32 (PcdVideoVerticalResolution, SetupVerticalResolution); + PcdSet32 (PcdConOutColumn, SetupTextModeColumn); + PcdSet32 (PcdConOutRow, SetupTextModeRow); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleTextOutProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < HandleCount; Index++) { + gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); + } + for (Index = 0; Index < HandleCount; Index++) { + gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); + } + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + break; + } + } + } + } + FreePool (Info); + } + } + + if (ModeNumber == MaxGopMode) { + // + // If the new resolution is not supported, return error. + // + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + /** This function is the main entry of the platform setup entry. The function will present the main menu of the system setup, @@ -996,7 +1177,11 @@ PlatformBdsEnterFrontPage ( } do { - + // + // Set proper video resolution and text mode for setup + // + ChangeModeForSetup (); + InitializeFrontPage (FALSE); // diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.h b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.h index a68eed9dbf..a118f91269 100644 --- a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.h +++ b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.h @@ -236,5 +236,20 @@ PlatformBdsEnterFrontPage ( IN BOOLEAN ConnectAllHappened ); +/** + This function will change video resolution and text mode for setup when setup is launched. + + @param None. + + @retval EFI_SUCCESS Mode is changed successfully. + @retval Others Mode failed to changed. + +**/ +EFI_STATUS +EFIAPI +ChangeModeForSetup ( + VOID + ); + #endif // _FRONT_PAGE_H_