]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Drivers / ConsolePrefDxe / ConsolePrefDxe.c
CommitLineData
d8e36289
AB
1/** @file\r
2*\r
3* Copyright (c) 2017, Linaro, Ltd. All rights reserved.\r
4*\r
878b807a 5* SPDX-License-Identifier: BSD-2-Clause-Patent\r
d8e36289
AB
6*\r
7**/\r
8\r
9#include <Uefi.h>\r
10#include <IndustryStandard/Acpi.h>\r
11#include <libfdt.h>\r
12#include <Library/BaseLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/DevicePathLib.h>\r
15#include <Library/HiiLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17#include <Library/UefiBootServicesTableLib.h>\r
18#include <Library/UefiDriverEntryPoint.h>\r
19#include <Library/UefiLib.h>\r
20#include <Library/UefiRuntimeServicesTableLib.h>\r
21\r
22#include <Protocol/AcpiTable.h>\r
23#include <Protocol/AcpiSystemDescriptionTable.h>\r
24\r
25#include "ConsolePrefDxe.h"\r
26\r
e7108d0e 27#define SPCR_SIG EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE\r
d8e36289 28\r
e7108d0e
MK
29extern UINT8 ConsolePrefHiiBin[];\r
30extern UINT8 ConsolePrefDxeStrings[];\r
d8e36289
AB
31\r
32typedef struct {\r
e7108d0e
MK
33 VENDOR_DEVICE_PATH VendorDevicePath;\r
34 EFI_DEVICE_PATH_PROTOCOL End;\r
d8e36289
AB
35} HII_VENDOR_DEVICE_PATH;\r
36\r
e7108d0e 37STATIC HII_VENDOR_DEVICE_PATH mConsolePrefDxeVendorDevicePath = {\r
d8e36289
AB
38 {\r
39 {\r
40 HARDWARE_DEVICE_PATH,\r
41 HW_VENDOR_DP,\r
42 {\r
e7108d0e
MK
43 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
44 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
d8e36289
AB
45 }\r
46 },\r
47 CONSOLE_PREF_FORMSET_GUID\r
48 },\r
49 {\r
50 END_DEVICE_PATH_TYPE,\r
51 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
52 {\r
e7108d0e
MK
53 (UINT8)(END_DEVICE_PATH_LENGTH),\r
54 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
d8e36289
AB
55 }\r
56 }\r
57};\r
58\r
e7108d0e 59STATIC EFI_EVENT mReadyToBootEvent;\r
d8e36289
AB
60\r
61STATIC\r
62EFI_STATUS\r
63InstallHiiPages (\r
64 VOID\r
65 )\r
66{\r
e7108d0e
MK
67 EFI_STATUS Status;\r
68 EFI_HII_HANDLE HiiHandle;\r
69 EFI_HANDLE DriverHandle;\r
d8e36289
AB
70\r
71 DriverHandle = NULL;\r
e7108d0e
MK
72 Status = gBS->InstallMultipleProtocolInterfaces (\r
73 &DriverHandle,\r
74 &gEfiDevicePathProtocolGuid,\r
75 &mConsolePrefDxeVendorDevicePath,\r
76 NULL\r
77 );\r
d8e36289
AB
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
e7108d0e
MK
82 HiiHandle = HiiAddPackages (\r
83 &gConsolePrefFormSetGuid,\r
84 DriverHandle,\r
85 ConsolePrefDxeStrings,\r
86 ConsolePrefHiiBin,\r
87 NULL\r
88 );\r
d8e36289
AB
89\r
90 if (HiiHandle == NULL) {\r
e7108d0e
MK
91 gBS->UninstallMultipleProtocolInterfaces (\r
92 DriverHandle,\r
d8e36289
AB
93 &gEfiDevicePathProtocolGuid,\r
94 &mConsolePrefDxeVendorDevicePath,\r
e7108d0e
MK
95 NULL\r
96 );\r
d8e36289
AB
97 return EFI_OUT_OF_RESOURCES;\r
98 }\r
e7108d0e 99\r
d8e36289
AB
100 return EFI_SUCCESS;\r
101}\r
102\r
103STATIC\r
104VOID\r
105RemoveDtStdoutPath (\r
106 VOID\r
e7108d0e 107 )\r
d8e36289
AB
108{\r
109 VOID *Dtb;\r
110 INT32 Node;\r
111 INT32 Error;\r
112 EFI_STATUS Status;\r
113\r
114 Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);\r
115 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
116 DEBUG ((\r
117 DEBUG_INFO,\r
118 "%a: could not retrieve DT blob - %r\n",\r
119 __FUNCTION__,\r
120 Status\r
121 ));\r
d8e36289
AB
122 return;\r
123 }\r
124\r
125 Node = fdt_path_offset (Dtb, "/chosen");\r
126 if (Node < 0) {\r
127 return;\r
128 }\r
129\r
130 Error = fdt_delprop (Dtb, Node, "stdout-path");\r
131 if (Error) {\r
e7108d0e
MK
132 DEBUG ((\r
133 DEBUG_INFO,\r
134 "%a: Failed to delete 'stdout-path' property: %a\n",\r
135 __FUNCTION__,\r
136 fdt_strerror (Error)\r
137 ));\r
d8e36289
AB
138 }\r
139}\r
140\r
141STATIC\r
142VOID\r
143RemoveSpcrTable (\r
144 VOID\r
145 )\r
146{\r
e7108d0e
MK
147 EFI_ACPI_SDT_PROTOCOL *Sdt;\r
148 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
149 EFI_STATUS Status;\r
150 UINTN TableIndex;\r
151 EFI_ACPI_SDT_HEADER *TableHeader;\r
152 EFI_ACPI_TABLE_VERSION TableVersion;\r
153 UINTN TableKey;\r
154\r
155 Status = gBS->LocateProtocol (\r
156 &gEfiAcpiTableProtocolGuid,\r
157 NULL,\r
158 (VOID **)&AcpiTable\r
159 );\r
d8e36289
AB
160 if (EFI_ERROR (Status)) {\r
161 return;\r
162 }\r
163\r
164 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&Sdt);\r
165 if (EFI_ERROR (Status)) {\r
166 return;\r
167 }\r
168\r
169 TableIndex = 0;\r
170 TableKey = 0;\r
171 TableHeader = NULL;\r
172\r
173 do {\r
e7108d0e
MK
174 Status = Sdt->GetAcpiTable (\r
175 TableIndex++,\r
176 &TableHeader,\r
177 &TableVersion,\r
178 &TableKey\r
179 );\r
d8e36289
AB
180 if (EFI_ERROR (Status)) {\r
181 break;\r
182 }\r
183\r
184 if (TableHeader->Signature != SPCR_SIG) {\r
185 continue;\r
186 }\r
187\r
188 Status = AcpiTable->UninstallAcpiTable (AcpiTable, TableKey);\r
189 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
190 DEBUG ((\r
191 DEBUG_WARN,\r
192 "%a: failed to uninstall SPCR table - %r\n",\r
193 __FUNCTION__,\r
194 Status\r
195 ));\r
d8e36289 196 }\r
e7108d0e 197\r
d8e36289
AB
198 break;\r
199 } while (TRUE);\r
200}\r
201\r
202STATIC\r
203VOID\r
7609c047 204EFIAPI\r
d8e36289
AB
205OnReadyToBoot (\r
206 IN EFI_EVENT Event,\r
207 IN VOID *Context\r
208 )\r
209{\r
e7108d0e
MK
210 CONSOLE_PREF_VARSTORE_DATA ConsolePref;\r
211 UINTN BufferSize;\r
212 EFI_STATUS Status;\r
213 VOID *Gop;\r
d8e36289
AB
214\r
215 BufferSize = sizeof (ConsolePref);\r
e7108d0e
MK
216 Status = gRT->GetVariable (\r
217 CONSOLE_PREF_VARIABLE_NAME,\r
218 &gConsolePrefFormSetGuid,\r
219 NULL,\r
220 &BufferSize,\r
221 &ConsolePref\r
222 );\r
d8e36289 223 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
224 DEBUG ((\r
225 DEBUG_ERROR,\r
226 "%a: variable '%s' could not be read - bailing!\n",\r
227 __FUNCTION__,\r
228 CONSOLE_PREF_VARIABLE_NAME\r
229 ));\r
d8e36289
AB
230 return;\r
231 }\r
232\r
233 if (ConsolePref.Console == CONSOLE_PREF_SERIAL) {\r
e7108d0e
MK
234 DEBUG ((\r
235 DEBUG_INFO,\r
236 "%a: serial console preferred - doing nothing\n",\r
237 __FUNCTION__\r
238 ));\r
d8e36289
AB
239 return;\r
240 }\r
241\r
242 //\r
243 // Check if any GOP instances exist: if so, disable stdout-path and SPCR\r
244 //\r
245 Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, &Gop);\r
246 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
247 DEBUG ((\r
248 DEBUG_INFO,\r
249 "%a: no GOP instances found - doing nothing (%r)\n",\r
250 __FUNCTION__,\r
251 Status\r
252 ));\r
d8e36289
AB
253 return;\r
254 }\r
255\r
256 RemoveDtStdoutPath ();\r
257 RemoveSpcrTable ();\r
258}\r
259\r
260/**\r
261 The entry point for ConsolePrefDxe driver.\r
262\r
263 @param[in] ImageHandle The image handle of the driver.\r
264 @param[in] SystemTable The system table.\r
265\r
266 @retval EFI_ALREADY_STARTED The driver already exists in system.\r
267 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of\r
268 resources.\r
c6a72cd7 269 @retval EFI_SUCCESS All the related protocols are installed on\r
d8e36289
AB
270 the driver.\r
271\r
272**/\r
273EFI_STATUS\r
274EFIAPI\r
275ConsolePrefDxeEntryPoint (\r
e7108d0e
MK
276 IN EFI_HANDLE ImageHandle,\r
277 IN EFI_SYSTEM_TABLE *SystemTable\r
d8e36289
AB
278 )\r
279{\r
e7108d0e
MK
280 EFI_STATUS Status;\r
281 CONSOLE_PREF_VARSTORE_DATA ConsolePref;\r
282 UINTN BufferSize;\r
d8e36289
AB
283\r
284 //\r
285 // Get the current console preference from the ConsolePref variable.\r
286 //\r
287 BufferSize = sizeof (ConsolePref);\r
e7108d0e
MK
288 Status = gRT->GetVariable (\r
289 CONSOLE_PREF_VARIABLE_NAME,\r
290 &gConsolePrefFormSetGuid,\r
291 NULL,\r
292 &BufferSize,\r
293 &ConsolePref\r
294 );\r
d8e36289 295 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
296 DEBUG ((\r
297 DEBUG_INFO,\r
d8e36289 298 "%a: no console preference found, defaulting to graphical\n",\r
e7108d0e
MK
299 __FUNCTION__\r
300 ));\r
d8e36289
AB
301 ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;\r
302 }\r
303\r
304 if (!EFI_ERROR (Status) &&\r
e7108d0e
MK
305 (ConsolePref.Console != CONSOLE_PREF_GRAPHICAL) &&\r
306 (ConsolePref.Console != CONSOLE_PREF_SERIAL))\r
307 {\r
308 DEBUG ((\r
309 DEBUG_WARN,\r
310 "%a: invalid value for %s, defaulting to graphical\n",\r
311 __FUNCTION__,\r
312 CONSOLE_PREF_VARIABLE_NAME\r
313 ));\r
d8e36289 314 ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;\r
e7108d0e 315 Status = EFI_INVALID_PARAMETER; // trigger setvar below\r
d8e36289
AB
316 }\r
317\r
318 //\r
319 // Write the newly selected value back to the variable store.\r
320 //\r
321 if (EFI_ERROR (Status)) {\r
322 ZeroMem (&ConsolePref.Reserved, sizeof (ConsolePref.Reserved));\r
e7108d0e
MK
323 Status = gRT->SetVariable (\r
324 CONSOLE_PREF_VARIABLE_NAME,\r
d8e36289
AB
325 &gConsolePrefFormSetGuid,\r
326 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
e7108d0e
MK
327 sizeof (ConsolePref),\r
328 &ConsolePref\r
329 );\r
d8e36289
AB
330\r
331 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
332 DEBUG ((\r
333 DEBUG_ERROR,\r
334 "%a: gRT->SetVariable () failed - %r\n",\r
335 __FUNCTION__,\r
336 Status\r
337 ));\r
d8e36289
AB
338 return Status;\r
339 }\r
340 }\r
341\r
e7108d0e
MK
342 Status = gBS->CreateEventEx (\r
343 EVT_NOTIFY_SIGNAL,\r
344 TPL_CALLBACK,\r
345 OnReadyToBoot,\r
346 NULL,\r
347 &gEfiEventReadyToBootGuid,\r
348 &mReadyToBootEvent\r
349 );\r
d8e36289
AB
350 ASSERT_EFI_ERROR (Status);\r
351\r
352 return InstallHiiPages ();\r
353}\r