]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
Nt32Pkg/PlatformBootManagerLib: zero EFI_GRAPHICS_OUTPUT_BLT_PIXEL.Reserved
[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 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_UNION Black;
266 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
267 UINT16 Timeout;
268
269 Timeout = PcdGet16 (PcdPlatformBootTimeOut);
270
271 Black.Raw = 0x00000000;
272 White.Raw = 0x00FFFFFF;
273
274 BootLogoUpdateProgress (
275 White.Pixel,
276 Black.Pixel,
277 L"Start boot option",
278 White.Pixel,
279 (Timeout - TimeoutRemain) * 100 / Timeout,
280 0
281 );
282 }