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