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