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