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