]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / BootManagerPolicyDxe / BootManagerPolicyDxe.c
CommitLineData
2e04a2f9
RN
1/** @file\r
2 This module produces Boot Manager Policy protocol.\r
3\r
d1102dba 4Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
2e04a2f9
RN
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <Protocol/BootManagerPolicy.h>\r
17#include <Protocol/ManagedNetwork.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/UefiLib.h>\r
21#include <Library/DevicePathLib.h>\r
22#include <Library/DebugLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24#include <Library/UefiRuntimeServicesTableLib.h>\r
25#include <Library/UefiBootManagerLib.h>\r
26\r
27CHAR16 mNetworkDeviceList[] = L"_NDL";\r
28\r
29/**\r
30 Connect all the system drivers to controllers and create the network device list in NV storage.\r
31\r
32 @retval EFI_SUCCESS Network devices are connected.\r
33 @retval EFI_DEVICE_ERROR No network device is connected.\r
34\r
35**/\r
36EFI_STATUS\r
37ConnectAllAndCreateNetworkDeviceList (\r
38 VOID\r
39 )\r
40{\r
41 EFI_STATUS Status;\r
42 EFI_HANDLE *Handles;\r
43 UINTN HandleCount;\r
44 EFI_DEVICE_PATH_PROTOCOL *SingleDevice;\r
45 EFI_DEVICE_PATH_PROTOCOL *Devices;\r
46 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
47\r
48 EfiBootManagerConnectAll ();\r
49\r
50 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles);\r
51 if (EFI_ERROR (Status)) {\r
52 Handles = NULL;\r
53 HandleCount = 0;\r
54 }\r
55\r
56 Devices = NULL;\r
57 while (HandleCount-- != 0) {\r
58 Status = gBS->HandleProtocol (Handles[HandleCount], &gEfiDevicePathProtocolGuid, (VOID **) &SingleDevice);\r
59 if (EFI_ERROR (Status) || (SingleDevice == NULL)) {\r
60 continue;\r
61 }\r
62 TempDevicePath = Devices;\r
63 Devices = AppendDevicePathInstance (Devices, SingleDevice);\r
64 if (TempDevicePath != NULL) {\r
65 FreePool (TempDevicePath);\r
66 }\r
67 }\r
68\r
69 if (Devices != NULL) {\r
70 Status = gRT->SetVariable (\r
71 mNetworkDeviceList,\r
72 &gEfiCallerIdGuid,\r
73 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
74 GetDevicePathSize (Devices),\r
75 Devices\r
76 );\r
77 //\r
78 // Fails to save the network device list to NV storage is not a fatal error.\r
79 // Only impact is performance.\r
80 //\r
81 FreePool (Devices);\r
82 }\r
83\r
84 return (Devices == NULL) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
85}\r
86\r
87/**\r
88 Connect the network devices.\r
89\r
90 @retval EFI_SUCCESS At least one network device was connected.\r
91 @retval EFI_DEVICE_ERROR Network devices were not connected due to an error.\r
92**/\r
93EFI_STATUS\r
94ConnectNetwork (\r
95 VOID\r
96 )\r
97{\r
98 EFI_STATUS Status;\r
99 BOOLEAN OneConnected;\r
100 EFI_DEVICE_PATH_PROTOCOL *Devices;\r
101 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
102 EFI_DEVICE_PATH_PROTOCOL *SingleDevice;\r
103 UINTN Size;\r
104\r
105 OneConnected = FALSE;\r
106 GetVariable2 (mNetworkDeviceList, &gEfiCallerIdGuid, (VOID **) &Devices, NULL);\r
107 TempDevicePath = Devices;\r
108 while (TempDevicePath != NULL) {\r
109 SingleDevice = GetNextDevicePathInstance (&TempDevicePath, &Size);\r
110 Status = EfiBootManagerConnectDevicePath (SingleDevice, NULL);\r
111 if (!EFI_ERROR (Status)) {\r
112 OneConnected = TRUE;\r
113 }\r
114 FreePool (SingleDevice);\r
115 }\r
116 if (Devices != NULL) {\r
117 FreePool (Devices);\r
118 }\r
119\r
120 if (OneConnected) {\r
121 return EFI_SUCCESS;\r
122 } else {\r
123 //\r
124 // Cached network devices list doesn't exist or is NOT valid.\r
125 //\r
126 return ConnectAllAndCreateNetworkDeviceList ();\r
127 }\r
128}\r
129\r
130/**\r
131 Connect a device path following the platforms EFI Boot Manager policy.\r
132\r
133 The ConnectDevicePath() function allows the caller to connect a DevicePath using the\r
134 same policy as the EFI Boot Manger.\r
135\r
136 @param[in] This A pointer to the EFI_BOOT_MANAGER_POLICY_PROTOCOL instance.\r
137 @param[in] DevicePath Points to the start of the EFI device path to connect.\r
138 If DevicePath is NULL then all the controllers in the\r
139 system will be connected using the platforms EFI Boot\r
140 Manager policy.\r
141 @param[in] Recursive If TRUE, then ConnectController() is called recursively\r
d1102dba 142 until the entire tree of controllers below the\r
2e04a2f9
RN
143 controller specified by DevicePath have been created.\r
144 If FALSE, then the tree of controllers is only expanded\r
145 one level. If DevicePath is NULL then Recursive is ignored.\r
146\r
147 @retval EFI_SUCCESS The DevicePath was connected.\r
148 @retval EFI_NOT_FOUND The DevicePath was not found.\r
149 @retval EFI_NOT_FOUND No driver was connected to DevicePath.\r
d1102dba 150 @retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device\r
2e04a2f9
RN
151 drivers on the DevicePath.\r
152 @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION.\r
153**/\r
154EFI_STATUS\r
155EFIAPI\r
156BootManagerPolicyConnectDevicePath (\r
157 IN EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,\r
158 IN EFI_DEVICE_PATH *DevicePath,\r
159 IN BOOLEAN Recursive\r
160 )\r
161{\r
162 EFI_STATUS Status;\r
163 EFI_HANDLE Controller;\r
164\r
165 if (EfiGetCurrentTpl () != TPL_APPLICATION) {\r
166 return EFI_UNSUPPORTED;\r
167 }\r
168\r
169 if (DevicePath == NULL) {\r
170 EfiBootManagerConnectAll ();\r
171 return EFI_SUCCESS;\r
172 }\r
173\r
174 if (Recursive) {\r
175 Status = EfiBootManagerConnectDevicePath (DevicePath, NULL);\r
176 } else {\r
177 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Controller);\r
178 if (!EFI_ERROR (Status)) {\r
179 Status = gBS->ConnectController (Controller, NULL, DevicePath, FALSE);\r
180 }\r
181 }\r
182 return Status;\r
183}\r
184/**\r
185 Connect a class of devices using the platform Boot Manager policy.\r
186\r
187 The ConnectDeviceClass() function allows the caller to request that the Boot\r
188 Manager connect a class of devices.\r
189\r
190 If Class is EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID then the Boot Manager will\r
d1102dba 191 use platform policy to connect consoles. Some platforms may restrict the\r
2e04a2f9
RN
192 number of consoles connected as they attempt to fast boot, and calling\r
193 ConnectDeviceClass() with a Class value of EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID\r
194 must connect the set of consoles that follow the Boot Manager platform policy,\r
195 and the EFI_SIMPLE_TEXT_INPUT_PROTOCOL, EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL, and\r
196 the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL are produced on the connected handles.\r
197 The Boot Manager may restrict which consoles get connect due to platform policy,\r
198 for example a security policy may require that a given console is not connected.\r
199\r
200 If Class is EFI_BOOT_MANAGER_POLICY_NETWORK_GUID then the Boot Manager will\r
201 connect the protocols the platforms supports for UEFI general purpose network\r
202 applications on one or more handles. If more than one network controller is\r
203 available a platform will connect, one, many, or all of the networks based\r
204 on platform policy. Connecting UEFI networking protocols, like EFI_DHCP4_PROTOCOL,\r
205 does not establish connections on the network. The UEFI general purpose network\r
206 application that called ConnectDeviceClass() may need to use the published\r
207 protocols to establish the network connection. The Boot Manager can optionally\r
208 have a policy to establish a network connection.\r
d1102dba 209\r
2e04a2f9
RN
210 If Class is EFI_BOOT_MANAGER_POLICY_CONNECT_ALL_GUID then the Boot Manager\r
211 will connect all UEFI drivers using the UEFI Boot Service\r
212 EFI_BOOT_SERVICES.ConnectController(). If the Boot Manager has policy\r
213 associated with connect all UEFI drivers this policy will be used.\r
214\r
215 A platform can also define platform specific Class values as a properly generated\r
216 EFI_GUID would never conflict with this specification.\r
217\r
218 @param[in] This A pointer to the EFI_BOOT_MANAGER_POLICY_PROTOCOL instance.\r
219 @param[in] Class A pointer to an EFI_GUID that represents a class of devices\r
220 that will be connected using the Boot Mangers platform policy.\r
221\r
222 @retval EFI_SUCCESS At least one devices of the Class was connected.\r
223 @retval EFI_DEVICE_ERROR Devices were not connected due to an error.\r
224 @retval EFI_NOT_FOUND The Class is not supported by the platform.\r
225 @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION.\r
d1102dba 226**/\r
2e04a2f9
RN
227EFI_STATUS\r
228EFIAPI\r
229BootManagerPolicyConnectDeviceClass (\r
230 IN EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,\r
231 IN EFI_GUID *Class\r
232 )\r
233{\r
234 if (EfiGetCurrentTpl () != TPL_APPLICATION) {\r
235 return EFI_UNSUPPORTED;\r
236 }\r
237\r
238 if (CompareGuid (Class, &gEfiBootManagerPolicyConnectAllGuid)) {\r
239 ConnectAllAndCreateNetworkDeviceList ();\r
240 return EFI_SUCCESS;\r
241 }\r
242\r
243 if (CompareGuid (Class, &gEfiBootManagerPolicyConsoleGuid)) {\r
244 return EfiBootManagerConnectAllDefaultConsoles ();\r
245 }\r
246\r
247 if (CompareGuid (Class, &gEfiBootManagerPolicyNetworkGuid)) {\r
248 return ConnectNetwork ();\r
249 }\r
250\r
251 return EFI_NOT_FOUND;\r
252}\r
253\r
254EFI_BOOT_MANAGER_POLICY_PROTOCOL mBootManagerPolicy = {\r
255 EFI_BOOT_MANAGER_POLICY_PROTOCOL_REVISION,\r
256 BootManagerPolicyConnectDevicePath,\r
257 BootManagerPolicyConnectDeviceClass\r
258};\r
259\r
260/**\r
261 Install Boot Manager Policy Protocol.\r
262\r
263 @param ImageHandle The image handle.\r
264 @param SystemTable The system table.\r
265\r
266 @retval EFI_SUCEESS The Boot Manager Policy protocol is successfully installed.\r
267 @retval Other Return status from gBS->InstallMultipleProtocolInterfaces().\r
268\r
269**/\r
270EFI_STATUS\r
271EFIAPI\r
272BootManagerPolicyInitialize (\r
273 IN EFI_HANDLE ImageHandle,\r
274 IN EFI_SYSTEM_TABLE *SystemTable\r
275 )\r
276{\r
277 EFI_HANDLE Handle;\r
278\r
279 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiBootManagerPolicyProtocolGuid);\r
280\r
281 Handle = NULL;\r
282 return gBS->InstallMultipleProtocolInterfaces (\r
283 &Handle,\r
284 &gEfiBootManagerPolicyProtocolGuid, &mBootManagerPolicy,\r
285 NULL\r
286 );\r
67b6269a 287}\r