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