]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
Move BdsDxe and GenericBdsLib to IntelFrameworkModulePkg, these modules need dependen...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
1 /** @file
2 The platform boot manager reference implementation
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 call back funtion is registered with Boot Manager formset.
35 When user selects a boot option, this call back function will
36 be triggered. The boot option is saved for later processing.
37
38
39 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
40 @param Action Specifies the type of action taken by the browser.
41 @param QuestionId A unique value which is sent to the original exporting driver
42 so that it can identify the type of data to expect.
43 @param Type The type of value for the question.
44 @param Value A pointer to the data being sent to the original exporting driver.
45 @param ActionRequest On return, points to the action requested by the callback function.
46
47 @retval EFI_SUCCESS The callback successfully handled the action.
48 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
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 Registers HII packages for the Boot Manger to HII Database.
105 It also registers the browser call back function.
106
107 @return Status of HiiLibCreateHiiDriverHandle() and gHiiDatabase->NewPackageList()
108
109 **/
110 EFI_STATUS
111 InitializeBootManager (
112 VOID
113 )
114 {
115 EFI_STATUS Status;
116 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
117
118 //
119 // Create driver handle used by HII database
120 //
121 Status = HiiLibCreateHiiDriverHandle (&gBootManagerPrivate.DriverHandle);
122 if (EFI_ERROR (Status)) {
123 return Status;
124 }
125
126 //
127 // Install Config Access protocol to driver handle
128 //
129 Status = gBS->InstallProtocolInterface (
130 &gBootManagerPrivate.DriverHandle,
131 &gEfiHiiConfigAccessProtocolGuid,
132 EFI_NATIVE_INTERFACE,
133 &gBootManagerPrivate.ConfigAccess
134 );
135 ASSERT_EFI_ERROR (Status);
136
137 //
138 // Publish our HII data
139 //
140 PackageList = HiiLibPreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsDxeStrings);
141 ASSERT (PackageList != NULL);
142
143 Status = gHiiDatabase->NewPackageList (
144 gHiiDatabase,
145 PackageList,
146 gBootManagerPrivate.DriverHandle,
147 &gBootManagerPrivate.HiiHandle
148 );
149 FreePool (PackageList);
150
151 return Status;
152 }
153
154 /**
155 This funtion invokees Boot Manager. If all devices have not a chance to be connected,
156 the connect all will be triggered. It then enumerate all boot options. If
157 a boot option from the Boot Manager page is selected, Boot Manager will boot
158 from this boot option.
159
160 **/
161 VOID
162 CallBootManager (
163 VOID
164 )
165 {
166 EFI_STATUS Status;
167 BDS_COMMON_OPTION *Option;
168 LIST_ENTRY *Link;
169 EFI_HII_UPDATE_DATA UpdateData;
170 CHAR16 *ExitData;
171 UINTN ExitDataSize;
172 EFI_STRING_ID Token;
173 EFI_INPUT_KEY Key;
174 LIST_ENTRY BdsBootOptionList;
175 CHAR16 *HelpString;
176 EFI_STRING_ID HelpToken;
177 UINT16 *TempStr;
178 EFI_HII_HANDLE HiiHandle;
179 EFI_BROWSER_ACTION_REQUEST ActionRequest;
180 UINTN TempSize;
181
182 gOption = NULL;
183 InitializeListHead (&BdsBootOptionList);
184
185 //
186 // Connect all prior to entering the platform setup menu.
187 //
188 if (!gConnectAllHappened) {
189 BdsLibConnectAllDriversToAllControllers ();
190 gConnectAllHappened = TRUE;
191 }
192 //
193 // BugBug: Here we can not remove the legacy refresh macro, so we need
194 // get the boot order every time from "BootOrder" variable.
195 // Recreate the boot option list base on the BootOrder variable
196 //
197 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
198
199 mBootOptionsList = &BdsBootOptionList;
200
201 HiiHandle = gBootManagerPrivate.HiiHandle;
202
203 //
204 // Allocate space for creation of UpdateData Buffer
205 //
206 UpdateData.BufferSize = 0x1000;
207 UpdateData.Offset = 0;
208 UpdateData.Data = AllocateZeroPool (0x1000);
209 ASSERT (UpdateData.Data != NULL);
210
211 mKeyInput = 0;
212
213 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
214 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
215
216 //
217 // At this stage we are creating a menu entry, thus the Keys are reproduceable
218 //
219 mKeyInput++;
220
221 //
222 // Don't display the boot option marked as LOAD_OPTION_HIDDEN
223 //
224 if (Option->Attribute & LOAD_OPTION_HIDDEN) {
225 continue;
226 }
227
228 HiiLibNewString (HiiHandle, &Token, Option->Description);
229
230 TempStr = DevicePathToStr (Option->DevicePath);
231 TempSize = StrSize (TempStr);
232 HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
233 ASSERT (HelpString != NULL);
234 StrCat (HelpString, L"Device Path : ");
235 StrCat (HelpString, TempStr);
236
237 HiiLibNewString (HiiHandle, &HelpToken, HelpString);
238
239 CreateActionOpCode (
240 mKeyInput,
241 Token,
242 HelpToken,
243 EFI_IFR_FLAG_CALLBACK,
244 0,
245 &UpdateData
246 );
247 }
248
249 IfrLibUpdateForm (
250 HiiHandle,
251 &mBootManagerGuid,
252 BOOT_MANAGER_FORM_ID,
253 LABEL_BOOT_OPTION,
254 FALSE,
255 &UpdateData
256 );
257 FreePool (UpdateData.Data);
258
259 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
260 Status = gFormBrowser2->SendForm (
261 gFormBrowser2,
262 &HiiHandle,
263 1,
264 NULL,
265 0,
266 NULL,
267 &ActionRequest
268 );
269 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
270 EnableResetRequired ();
271 }
272
273 if (gOption == NULL) {
274 return ;
275 }
276
277 //
278 //Will leave browser, check any reset required change is applied? if yes, reset system
279 //
280 SetupResetReminder ();
281
282 //
283 // parse the selected option
284 //
285 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
286
287 if (!EFI_ERROR (Status)) {
288 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
289 PlatformBdsBootSuccess (gOption);
290 } else {
291 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
292 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
293 gST->ConOut->OutputString (
294 gST->ConOut,
295 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
296 );
297 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
298 }
299 }