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