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