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