]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
1 /*++
2
3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 BootManager.c
15
16 Abstract:
17
18 The platform boot manager reference implement
19
20 --*/
21
22 #include "BootManager.h"
23
24 UINT16 mKeyInput;
25 EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
26 LIST_ENTRY *mBootOptionsList;
27 BDS_COMMON_OPTION *gOption;
28
29 BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {
30 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,
31 NULL,
32 NULL,
33 {
34 FakeExtractConfig,
35 FakeRouteConfig,
36 BootManagerCallback
37 }
38 };
39
40 EFI_STATUS
41 EFIAPI
42 BootManagerCallback (
43 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
44 IN EFI_BROWSER_ACTION Action,
45 IN EFI_QUESTION_ID QuestionId,
46 IN UINT8 Type,
47 IN EFI_IFR_TYPE_VALUE *Value,
48 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
49 )
50 /*++
51
52 Routine Description:
53 This function processes the results of changes in configuration.
54
55 Arguments:
56 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
57 Action - Specifies the type of action taken by the browser.
58 QuestionId - A unique value which is sent to the original exporting driver
59 so that it can identify the type of data to expect.
60 Type - The type of value for the question.
61 Value - A pointer to the data being sent to the original exporting driver.
62 ActionRequest - On return, points to the action requested by the callback function.
63
64 Returns:
65 EFI_SUCCESS - The callback successfully handled the action.
66 EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
67 EFI_DEVICE_ERROR - The variable could not be saved.
68 EFI_UNSUPPORTED - The specified Action is not supported by the callback.
69
70 --*/
71 {
72 BDS_COMMON_OPTION *Option;
73 LIST_ENTRY *Link;
74 UINT16 KeyCount;
75
76 if ((Value == NULL) || (ActionRequest == NULL)) {
77 return EFI_INVALID_PARAMETER;
78 }
79
80 //
81 // Initialize the key count
82 //
83 KeyCount = 0;
84
85 for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {
86 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
87
88 KeyCount++;
89
90 gOption = Option;
91
92 //
93 // Is this device the one chosen?
94 //
95 if (KeyCount == QuestionId) {
96 //
97 // Assigning the returned Key to a global allows the original routine to know what was chosen
98 //
99 mKeyInput = QuestionId;
100
101 //
102 // Request to exit SendForm(), so that we could boot the selected option
103 //
104 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
105 break;
106 }
107 }
108
109 return EFI_SUCCESS;
110 }
111
112 EFI_STATUS
113 InitializeBootManager (
114 VOID
115 )
116 /*++
117
118 Routine Description:
119
120 Initialize HII information for the FrontPage
121
122 Arguments:
123 None
124
125 Returns:
126
127 --*/
128 {
129 EFI_STATUS Status;
130 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
131
132 //
133 // Create driver handle used by HII database
134 //
135 Status = HiiLibCreateHiiDriverHandle (&gBootManagerPrivate.DriverHandle);
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139
140 //
141 // Install Config Access protocol to driver handle
142 //
143 Status = gBS->InstallProtocolInterface (
144 &gBootManagerPrivate.DriverHandle,
145 &gEfiHiiConfigAccessProtocolGuid,
146 EFI_NATIVE_INTERFACE,
147 &gBootManagerPrivate.ConfigAccess
148 );
149 ASSERT_EFI_ERROR (Status);
150
151 //
152 // Publish our HII data
153 //
154 PackageList = PreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsStrings);
155 ASSERT (PackageList != NULL);
156
157 Status = gHiiDatabase->NewPackageList (
158 gHiiDatabase,
159 PackageList,
160 gBootManagerPrivate.DriverHandle,
161 &gBootManagerPrivate.HiiHandle
162 );
163 FreePool (PackageList);
164
165 return Status;
166 }
167
168 VOID
169 CallBootManager (
170 VOID
171 )
172 /*++
173
174 Routine Description:
175 Hook to enable UI timeout override behavior.
176
177 Arguments:
178 BdsDeviceList - Device List that BDS needs to connect.
179
180 Entry - Pointer to current Boot Entry.
181
182 Returns:
183 NONE
184
185 --*/
186 {
187 EFI_STATUS Status;
188 BDS_COMMON_OPTION *Option;
189 LIST_ENTRY *Link;
190 EFI_HII_UPDATE_DATA UpdateData;
191 CHAR16 *ExitData;
192 UINTN ExitDataSize;
193 EFI_STRING_ID Token;
194 EFI_INPUT_KEY Key;
195 LIST_ENTRY BdsBootOptionList;
196 CHAR16 *HelpString;
197 EFI_STRING_ID HelpToken;
198 UINT16 *TempStr;
199 EFI_HII_HANDLE HiiHandle;
200 EFI_BROWSER_ACTION_REQUEST ActionRequest;
201 UINTN TempSize;
202
203 gOption = NULL;
204 InitializeListHead (&BdsBootOptionList);
205
206 //
207 // Connect all prior to entering the platform setup menu.
208 //
209 if (!gConnectAllHappened) {
210 BdsLibConnectAllDriversToAllControllers ();
211 gConnectAllHappened = TRUE;
212 }
213 //
214 // BugBug: Here we can not remove the legacy refresh macro, so we need
215 // get the boot order every time from "BootOrder" variable.
216 // Recreate the boot option list base on the BootOrder variable
217 //
218 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
219
220 mBootOptionsList = &BdsBootOptionList;
221
222 HiiHandle = gBootManagerPrivate.HiiHandle;
223
224 //
225 // Allocate space for creation of UpdateData Buffer
226 //
227 UpdateData.BufferSize = 0x1000;
228 UpdateData.Offset = 0;
229 UpdateData.Data = AllocateZeroPool (0x1000);
230 ASSERT (UpdateData.Data != NULL);
231
232 mKeyInput = 0;
233
234 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
235 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
236
237 //
238 // At this stage we are creating a menu entry, thus the Keys are reproduceable
239 //
240 mKeyInput++;
241
242 //
243 // Don't display the boot option marked as LOAD_OPTION_HIDDEN
244 //
245 if (Option->Attribute & LOAD_OPTION_HIDDEN) {
246 continue;
247 }
248
249 IfrLibNewString (HiiHandle, &Token, Option->Description);
250
251 TempStr = DevicePathToStr (Option->DevicePath);
252 TempSize = StrSize (TempStr);
253 HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
254 StrCat (HelpString, L"Device Path : ");
255 StrCat (HelpString, TempStr);
256
257 IfrLibNewString (HiiHandle, &HelpToken, HelpString);
258
259 CreateActionOpCode (
260 mKeyInput,
261 Token,
262 HelpToken,
263 EFI_IFR_FLAG_CALLBACK,
264 0,
265 &UpdateData
266 );
267 }
268
269 IfrLibUpdateForm (
270 HiiHandle,
271 &mBootManagerGuid,
272 BOOT_MANAGER_FORM_ID,
273 LABEL_BOOT_OPTION,
274 FALSE,
275 &UpdateData
276 );
277 FreePool (UpdateData.Data);
278
279 //
280 // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
281 //
282 gBS->RestoreTPL (TPL_APPLICATION);
283
284 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
285 Status = gFormBrowser2->SendForm (
286 gFormBrowser2,
287 &HiiHandle,
288 1,
289 NULL,
290 0,
291 NULL,
292 &ActionRequest
293 );
294 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
295 EnableResetRequired ();
296 }
297
298 if (gOption == NULL) {
299 gBS->RaiseTPL (TPL_APPLICATION);
300 return ;
301 }
302
303 //
304 //Will leave browser, check any reset required change is applied? if yes, reset system
305 //
306 SetupResetReminder ();
307
308 //
309 // Raise the TPL level back to TPL_APPLICATION
310 //
311 gBS->RaiseTPL (TPL_APPLICATION);
312
313 //
314 // parse the selected option
315 //
316 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
317
318 if (!EFI_ERROR (Status)) {
319 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
320 PlatformBdsBootSuccess (gOption);
321 } else {
322 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
323 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
324 gST->ConOut->OutputString (
325 gST->ConOut,
326 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
327 );
328 gBS->RestoreTPL (TPL_APPLICATION);
329 //
330 // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
331 //
332 gBS->RaiseTPL (TPL_APPLICATION);
333 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
334 }
335 }