]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/PlatformBdsDxe/Generic/BootMngr/BootManager.c
add in PlatformBds.inf
[mirror_edk2.git] / Nt32Pkg / PlatformBdsDxe / Generic / BootMngr / BootManager.c
1 /*++
2
3 Copyright (c) 2006 - 2007, 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 common header file for this module.
23 //
24 #include "CommonHeader.h"
25
26 #include "BootManager.h"
27
28 UINT16 mKeyInput;
29 LIST_ENTRY *mBootOptionsList;
30 BDS_COMMON_OPTION *gOption;
31 EFI_HII_HANDLE gBootManagerHandle;
32 EFI_HANDLE BootManagerCallbackHandle;
33 EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback;
34 EFI_GUID gBmGuid = BOOT_MANAGER_GUID;
35
36 extern EFI_FORM_BROWSER_PROTOCOL *gBrowser;
37 extern UINT8 BootManagerVfrBin[];
38 extern UINT8 BdsStrings[];
39 extern BOOLEAN gConnectAllHappened;
40
41 EFI_STATUS
42 EFIAPI
43 BootManagerCallbackRoutine (
44 IN EFI_FORM_CALLBACK_PROTOCOL *This,
45 IN UINT16 KeyValue,
46 IN EFI_IFR_DATA_ARRAY *DataArray,
47 OUT EFI_HII_CALLBACK_PACKET **Packet
48 )
49 /*++
50
51 Routine Description:
52
53 This is the function that is called to provide results data to the driver. This data
54 consists of a unique key which is used to identify what data is either being passed back
55 or being asked for.
56
57 Arguments:
58
59 KeyValue - A unique value which is sent to the original exporting driver so that it
60 can identify the type of data to expect. The format of the data tends to
61 vary based on the op-code that geerated the callback.
62
63 Data - A pointer to the data being sent to the original exporting driver.
64
65 Returns:
66
67 --*/
68 {
69 BDS_COMMON_OPTION *Option;
70 LIST_ENTRY *Link;
71 UINT16 KeyCount;
72 EFI_HII_CALLBACK_PACKET *DataPacket;
73
74 //
75 // Initialize the key count
76 //
77 KeyCount = 0;
78
79 for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {
80 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
81
82 KeyCount++;
83
84 gOption = Option;
85
86 //
87 // Is this device the one chosen?
88 //
89 if (KeyCount == KeyValue) {
90 //
91 // Assigning the returned Key to a global allows the original routine to know what was chosen
92 //
93 mKeyInput = KeyValue;
94
95 *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);
96 ASSERT (*Packet != NULL);
97
98 //
99 // Assign the buffer address to DataPacket
100 //
101 DataPacket = *Packet;
102
103 DataPacket->DataArray.EntryCount = 1;
104 DataPacket->DataArray.NvRamMap = NULL;
105 ((EFI_IFR_DATA_ENTRY *) (((EFI_IFR_DATA_ARRAY *)DataPacket) + 1))->Flags = EXIT_REQUIRED | NV_NOT_CHANGED;
106 return EFI_SUCCESS;
107 } else {
108 continue;
109 }
110 }
111
112 return EFI_SUCCESS;
113 }
114
115 VOID
116 CallBootManager (
117 VOID
118 )
119 /*++
120
121 Routine Description:
122 Hook to enable UI timeout override behavior.
123
124 Arguments:
125 BdsDeviceList - Device List that BDS needs to connect.
126
127 Entry - Pointer to current Boot Entry.
128
129 Returns:
130 NONE
131
132 --*/
133 {
134 EFI_STATUS Status;
135 EFI_HII_PACKAGES *PackageList;
136 BDS_COMMON_OPTION *Option;
137 LIST_ENTRY *Link;
138 EFI_HII_UPDATE_DATA *UpdateData;
139 CHAR16 *ExitData;
140 UINTN ExitDataSize;
141 STRING_REF Token;
142 STRING_REF LastToken;
143 EFI_INPUT_KEY Key;
144 UINT8 *Location;
145 EFI_GUID BmGuid;
146 LIST_ENTRY BdsBootOptionList;
147 BOOLEAN BootMngrMenuResetRequired;
148
149 gOption = NULL;
150 InitializeListHead (&BdsBootOptionList);
151
152 //
153 // Connect all prior to entering the platform setup menu.
154 //
155 if (!gConnectAllHappened) {
156 BdsLibConnectAllDriversToAllControllers ();
157 gConnectAllHappened = TRUE;
158 }
159 //
160 // BugBug: Here we can not remove the legacy refresh macro, so we need
161 // get the boot order every time from "BootOrder" variable.
162 // Recreate the boot option list base on the BootOrder variable
163 //
164 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
165
166 //
167 // This GUID must be the same as what is defined in BootManagerVfr.vfr
168 //
169 BmGuid = gBmGuid;
170
171 mBootOptionsList = &BdsBootOptionList;
172
173 //
174 // Post our VFR to the HII database
175 //
176 PackageList = PreparePackages (2, &BmGuid, BootManagerVfrBin, BdsStrings);
177 Status = Hii->NewPack (Hii, PackageList, &gBootManagerHandle);
178 FreePool (PackageList);
179
180 //
181 // This example does not implement worker functions
182 // for the NV accessor functions. Only a callback evaluator
183 //
184 BootManagerCallback.NvRead = NULL;
185 BootManagerCallback.NvWrite = NULL;
186 BootManagerCallback.Callback = BootManagerCallbackRoutine;
187
188 //
189 // Install protocol interface
190 //
191 BootManagerCallbackHandle = NULL;
192 Status = gBS->InstallProtocolInterface (
193 &BootManagerCallbackHandle,
194 &gEfiFormCallbackProtocolGuid,
195 EFI_NATIVE_INTERFACE,
196 &BootManagerCallback
197 );
198 ASSERT_EFI_ERROR (Status);
199
200 LastToken = 0;
201 Hii->NewString (Hii, NULL, gBootManagerHandle, &LastToken, L" ");
202
203 //
204 // Allocate space for creation of UpdateData Buffer
205 //
206 UpdateData = AllocateZeroPool (0x1000);
207 ASSERT (UpdateData != NULL);
208
209 //
210 // Flag update pending in FormSet
211 //
212 UpdateData->FormSetUpdate = TRUE;
213 //
214 // Register CallbackHandle data for FormSet
215 //
216 UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) BootManagerCallbackHandle;
217 UpdateData->FormUpdate = FALSE;
218 UpdateData->FormTitle = 0;
219 UpdateData->DataCount = 1;
220
221 //
222 // Create blank space. Since when we update the contents of IFR data at a label, it is
223 // inserted at the location of the label. So if you want to add a string with an empty
224 // space afterwards, you need to add the space first and then the string like below.
225 //
226 Status = CreateSubTitleOpCode (
227 LastToken, // Token Value for the string
228 &UpdateData->Data // Buffer containing created op-code
229 );
230
231 Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);
232
233 //
234 // Create "Boot Option Menu" title
235 //
236 Status = CreateSubTitleOpCode (
237 STRING_TOKEN (STR_BOOT_OPTION_BANNER), // Token Value for the string
238 &UpdateData->Data // Buffer containing created op-code
239 );
240
241 Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);
242
243 Token = LastToken;
244 mKeyInput = 0;
245
246 UpdateData->DataCount = 0;
247 Location = (UINT8 *) &UpdateData->Data;
248
249 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
250 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
251
252 //
253 // At this stage we are creating a menu entry, thus the Keys are reproduceable
254 //
255 mKeyInput++;
256 Token++;
257
258 Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);
259
260 //
261 // If we got an error it is almost certainly due to the token value being invalid.
262 // Therefore we will set the Token to 0 to automatically add a token.
263 //
264 if (EFI_ERROR (Status)) {
265 Token = 0;
266 Status = Hii->NewString (Hii, NULL, gBootManagerHandle, &Token, Option->Description);
267 }
268
269 Status = CreateGotoOpCode (
270 0x1000, // Form ID
271 Token, // Token Value for the string
272 0, // Help String (none)
273 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS, // The Op-Code flags
274 mKeyInput, // The Key to get a callback on
275 Location // Buffer containing created op-code
276 );
277
278 UpdateData->DataCount++;
279 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
280
281 }
282
283 Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0001, TRUE, UpdateData);
284
285 UpdateData->DataCount = 1;
286
287 //
288 // Create "Boot Option Menu" title
289 //
290 Status = CreateSubTitleOpCode (
291 STRING_TOKEN (STR_HELP_FOOTER), // Token Value for the string
292 &UpdateData->Data // Buffer containing created op-code
293 );
294
295 Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
296
297 Status = CreateSubTitleOpCode (
298 LastToken, // Token Value for the string
299 &UpdateData->Data // Buffer containing created op-code
300 );
301
302 Hii->UpdateForm (Hii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
303
304 FreePool (UpdateData);
305
306 ASSERT (gBrowser);
307
308 BootMngrMenuResetRequired = FALSE;
309 gBrowser->SendForm (
310 gBrowser,
311 TRUE,
312 &gBootManagerHandle,
313 1,
314 NULL,
315 NULL,
316 NULL,
317 NULL,
318 &BootMngrMenuResetRequired
319 );
320
321 if (BootMngrMenuResetRequired) {
322 EnableResetRequired ();
323 }
324
325 Hii->ResetStrings (Hii, gBootManagerHandle);
326
327 if (gOption == NULL) {
328 return ;
329 }
330
331 //
332 //Will leave browser, check any reset required change is applied? if yes, reset system
333 //
334 SetupResetReminder ();
335
336 //
337 // BugBug: This code looks repeated from the BDS. Need to save code space.
338 //
339
340 //
341 // parse the selected option
342 //
343 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
344
345 if (!EFI_ERROR (Status)) {
346 PlatformBdsBootSuccess (gOption);
347 } else {
348 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
349 gST->ConOut->OutputString (
350 gST->ConOut,
351 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
352 );
353
354 //
355 // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
356 //
357
358 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
359 }
360 }