1 /** @file 2 This file include all platform action which can be customized 3 by IBV/OEM. 4 5 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "PlatformBootManager.h" 17 18 /** 19 Perform the platform diagnostic, such like test memory. OEM/IBV also 20 can customize this function to support specific platform diagnostic. 21 22 @param MemoryTestLevel The memory test intensive level 23 @param QuietBoot Indicate if need to enable the quiet boot 24 25 **/ 26 VOID 27 PlatformBootManagerDiagnostics ( 28 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, 29 IN BOOLEAN QuietBoot 30 ) 31 { 32 EFI_STATUS Status; 33 34 // 35 // Here we can decide if we need to show 36 // the diagnostics screen 37 // Notes: this quiet boot code should be remove 38 // from the graphic lib 39 // 40 if (QuietBoot) { 41 BootLogoEnableLogo (ImageFormatBmp, PcdGetPtr(PcdLogoFile), EdkiiPlatformLogoDisplayAttributeCenter, 0, 0); 42 43 // 44 // Perform system diagnostic 45 // 46 Status = PlatformBootManagerMemoryTest (MemoryTestLevel); 47 if (EFI_ERROR (Status)) { 48 BootLogoDisableLogo (); 49 } 50 51 return; 52 } 53 54 // 55 // Perform system diagnostic 56 // 57 Status = PlatformBootManagerMemoryTest (MemoryTestLevel); 58 } 59 60 /** 61 Return the index of the load option in the load option array. 62 63 The function consider two load options are equal when the 64 OptionType, Attributes, Description, FilePath and OptionalData are equal. 65 66 @param Key Pointer to the load option to be found. 67 @param Array Pointer to the array of load options to be found. 68 @param Count Number of entries in the Array. 69 70 @retval -1 Key wasn't found in the Array. 71 @retval 0 ~ Count-1 The index of the Key in the Array. 72 **/ 73 INTN 74 PlatformFindLoadOption ( 75 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key, 76 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array, 77 IN UINTN Count 78 ) 79 { 80 UINTN Index; 81 82 for (Index = 0; Index < Count; Index++) { 83 if ((Key->OptionType == Array[Index].OptionType) && 84 (Key->Attributes == Array[Index].Attributes) && 85 (StrCmp (Key->Description, Array[Index].Description) == 0) && 86 (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) && 87 (Key->OptionalDataSize == Array[Index].OptionalDataSize) && 88 (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) { 89 return (INTN) Index; 90 } 91 } 92 93 return -1; 94 } 95 96 VOID 97 PlatformRegisterFvBootOption ( 98 EFI_GUID *FileGuid, 99 CHAR16 *Description, 100 UINT32 Attributes 101 ) 102 { 103 EFI_STATUS Status; 104 UINTN OptionIndex; 105 EFI_BOOT_MANAGER_LOAD_OPTION NewOption; 106 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; 107 UINTN BootOptionCount; 108 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; 109 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; 110 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 111 112 Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); 113 ASSERT_EFI_ERROR (Status); 114 115 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); 116 DevicePath = AppendDevicePathNode ( 117 DevicePathFromHandle (LoadedImage->DeviceHandle), 118 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode 119 ); 120 121 Status = EfiBootManagerInitializeLoadOption ( 122 &NewOption, 123 LoadOptionNumberUnassigned, 124 LoadOptionTypeBoot, 125 Attributes, 126 Description, 127 DevicePath, 128 NULL, 129 0 130 ); 131 if (!EFI_ERROR (Status)) { 132 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); 133 134 OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount); 135 136 if (OptionIndex == -1) { 137 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1); 138 ASSERT_EFI_ERROR (Status); 139 } 140 EfiBootManagerFreeLoadOption (&NewOption); 141 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); 142 } 143 } 144 145 /** 146 Do the platform specific action before the console is connected. 147 148 Such as: 149 Update console variable; 150 Register new Driver#### or Boot####; 151 Signal ReadyToLock event. 152 **/ 153 VOID 154 EFIAPI 155 PlatformBootManagerBeforeConsole ( 156 VOID 157 ) 158 { 159 UINTN Index; 160 EFI_STATUS Status; 161 WIN_NT_SYSTEM_CONFIGURATION *Configuration; 162 EFI_INPUT_KEY Enter; 163 EFI_INPUT_KEY F2; 164 EFI_BOOT_MANAGER_LOAD_OPTION BootOption; 165 166 GetVariable2 (L"Setup", &gEfiWinNtSystemConfigGuid, (VOID **) &Configuration, NULL); 167 if (Configuration != NULL) { 168 // 169 // SetupVariable is corrupt 170 // 171 Configuration->ConOutRow = PcdGet32 (PcdConOutColumn); 172 Configuration->ConOutColumn = PcdGet32 (PcdConOutRow); 173 174 Status = gRT->SetVariable ( 175 L"Setup", 176 &gEfiWinNtSystemConfigGuid, 177 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 178 sizeof (WIN_NT_SYSTEM_CONFIGURATION), 179 Configuration 180 ); 181 if (EFI_ERROR (Status)) { 182 DEBUG ((EFI_D_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status)); 183 } 184 FreePool (Configuration); 185 } 186 187 // 188 // Update the ocnsole variables. 189 // 190 for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) { 191 if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { 192 EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL); 193 } 194 195 if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { 196 EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL); 197 } 198 199 if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { 200 EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL); 201 } 202 } 203 204 // 205 // Register ENTER as CONTINUE key 206 // 207 Enter.ScanCode = SCAN_NULL; 208 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; 209 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); 210 // 211 // Map F2 to Boot Manager Menu 212 // 213 F2.ScanCode = SCAN_F2; 214 F2.UnicodeChar = CHAR_NULL; 215 EfiBootManagerGetBootManagerMenu (&BootOption); 216 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL); 217 // 218 // Register UEFI Shell 219 // 220 PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE); 221 } 222 223 /** 224 Do the platform specific action after the console is connected. 225 226 Such as: 227 Dynamically switch output mode; 228 Signal console ready platform customized event; 229 Run diagnostics like memory testing; 230 Connect certain devices; 231 Dispatch aditional option roms. 232 **/ 233 VOID 234 EFIAPI 235 PlatformBootManagerAfterConsole ( 236 VOID 237 ) 238 { 239 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; 240 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; 241 242 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0; 243 White.Blue = White.Green = White.Red = White.Reserved = 0xFF; 244 245 EfiBootManagerConnectAll (); 246 EfiBootManagerRefreshAllBootOption (); 247 248 PlatformBootManagerDiagnostics (QUICK, TRUE); 249 250 PrintXY (10, 10, &White, &Black, L"F2 to enter Boot Manager Menu. "); 251 PrintXY (10, 30, &White, &Black, L"Enter to boot directly."); 252 } 253 254 /** 255 This function is called each second during the boot manager waits the timeout. 256 257 @param TimeoutRemain The remaining timeout. 258 **/ 259 VOID 260 EFIAPI 261 PlatformBootManagerWaitCallback ( 262 UINT16 TimeoutRemain 263 ) 264 { 265 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; 266 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; 267 UINT16 Timeout; 268 269 Timeout = PcdGet16 (PcdPlatformBootTimeOut); 270 271 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0; 272 White.Blue = White.Green = White.Red = White.Reserved = 0xFF; 273 274 BootLogoUpdateProgress ( 275 White, 276 Black, 277 L"Start boot option", 278 White, 279 (Timeout - TimeoutRemain) * 100 / Timeout, 280 0 281 ); 282 } 283