]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
EmbeddedPkg: add missing EFIAPI calling convention specifiers
[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
27#define SPCR_SIG EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE\r
28\r
29extern UINT8 ConsolePrefHiiBin[];\r
30extern UINT8 ConsolePrefDxeStrings[];\r
31\r
32typedef struct {\r
33 VENDOR_DEVICE_PATH VendorDevicePath;\r
34 EFI_DEVICE_PATH_PROTOCOL End;\r
35} HII_VENDOR_DEVICE_PATH;\r
36\r
37STATIC HII_VENDOR_DEVICE_PATH mConsolePrefDxeVendorDevicePath = {\r
38 {\r
39 {\r
40 HARDWARE_DEVICE_PATH,\r
41 HW_VENDOR_DP,\r
42 {\r
43 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
44 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
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
53 (UINT8) (END_DEVICE_PATH_LENGTH),\r
54 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
55 }\r
56 }\r
57};\r
58\r
59STATIC EFI_EVENT mReadyToBootEvent;\r
60\r
61STATIC\r
62EFI_STATUS\r
63InstallHiiPages (\r
64 VOID\r
65 )\r
66{\r
67 EFI_STATUS Status;\r
68 EFI_HII_HANDLE HiiHandle;\r
69 EFI_HANDLE DriverHandle;\r
70\r
71 DriverHandle = NULL;\r
72 Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,\r
73 &gEfiDevicePathProtocolGuid,\r
74 &mConsolePrefDxeVendorDevicePath,\r
75 NULL);\r
76 if (EFI_ERROR (Status)) {\r
77 return Status;\r
78 }\r
79\r
80 HiiHandle = HiiAddPackages (&gConsolePrefFormSetGuid,\r
81 DriverHandle,\r
82 ConsolePrefDxeStrings,\r
83 ConsolePrefHiiBin,\r
84 NULL);\r
85\r
86 if (HiiHandle == NULL) {\r
87 gBS->UninstallMultipleProtocolInterfaces (DriverHandle,\r
88 &gEfiDevicePathProtocolGuid,\r
89 &mConsolePrefDxeVendorDevicePath,\r
90 NULL);\r
91 return EFI_OUT_OF_RESOURCES;\r
92 }\r
93 return EFI_SUCCESS;\r
94}\r
95\r
96STATIC\r
97VOID\r
98RemoveDtStdoutPath (\r
99 VOID\r
100)\r
101{\r
102 VOID *Dtb;\r
103 INT32 Node;\r
104 INT32 Error;\r
105 EFI_STATUS Status;\r
106\r
107 Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);\r
108 if (EFI_ERROR (Status)) {\r
109 DEBUG ((DEBUG_INFO, "%a: could not retrieve DT blob - %r\n", __FUNCTION__,\r
110 Status));\r
111 return;\r
112 }\r
113\r
114 Node = fdt_path_offset (Dtb, "/chosen");\r
115 if (Node < 0) {\r
116 return;\r
117 }\r
118\r
119 Error = fdt_delprop (Dtb, Node, "stdout-path");\r
120 if (Error) {\r
121 DEBUG ((DEBUG_INFO, "%a: Failed to delete 'stdout-path' property: %a\n",\r
122 __FUNCTION__, fdt_strerror (Error)));\r
123 }\r
124}\r
125\r
126STATIC\r
127VOID\r
128RemoveSpcrTable (\r
129 VOID\r
130 )\r
131{\r
132 EFI_ACPI_SDT_PROTOCOL *Sdt;\r
133 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
134 EFI_STATUS Status;\r
135 UINTN TableIndex;\r
136 EFI_ACPI_SDT_HEADER *TableHeader;\r
137 EFI_ACPI_TABLE_VERSION TableVersion;\r
138 UINTN TableKey;\r
139\r
140 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL,\r
141 (VOID **)&AcpiTable);\r
142 if (EFI_ERROR (Status)) {\r
143 return;\r
144 }\r
145\r
146 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&Sdt);\r
147 if (EFI_ERROR (Status)) {\r
148 return;\r
149 }\r
150\r
151 TableIndex = 0;\r
152 TableKey = 0;\r
153 TableHeader = NULL;\r
154\r
155 do {\r
156 Status = Sdt->GetAcpiTable (TableIndex++, &TableHeader, &TableVersion,\r
157 &TableKey);\r
158 if (EFI_ERROR (Status)) {\r
159 break;\r
160 }\r
161\r
162 if (TableHeader->Signature != SPCR_SIG) {\r
163 continue;\r
164 }\r
165\r
166 Status = AcpiTable->UninstallAcpiTable (AcpiTable, TableKey);\r
167 if (EFI_ERROR (Status)) {\r
168 DEBUG ((DEBUG_WARN, "%a: failed to uninstall SPCR table - %r\n",\r
169 __FUNCTION__, Status));\r
170 }\r
171 break;\r
172 } while (TRUE);\r
173}\r
174\r
175STATIC\r
176VOID\r
7609c047 177EFIAPI\r
d8e36289
AB
178OnReadyToBoot (\r
179 IN EFI_EVENT Event,\r
180 IN VOID *Context\r
181 )\r
182{\r
183 CONSOLE_PREF_VARSTORE_DATA ConsolePref;\r
184 UINTN BufferSize;\r
185 EFI_STATUS Status;\r
186 VOID *Gop;\r
187\r
188 BufferSize = sizeof (ConsolePref);\r
189 Status = gRT->GetVariable (CONSOLE_PREF_VARIABLE_NAME,\r
190 &gConsolePrefFormSetGuid, NULL, &BufferSize, &ConsolePref);\r
191 if (EFI_ERROR (Status)) {\r
192 DEBUG ((DEBUG_ERROR,\r
193 "%a: variable '%s' could not be read - bailing!\n", __FUNCTION__,\r
194 CONSOLE_PREF_VARIABLE_NAME));\r
195 return;\r
196 }\r
197\r
198 if (ConsolePref.Console == CONSOLE_PREF_SERIAL) {\r
199 DEBUG ((DEBUG_INFO,\r
200 "%a: serial console preferred - doing nothing\n", __FUNCTION__));\r
201 return;\r
202 }\r
203\r
204 //\r
205 // Check if any GOP instances exist: if so, disable stdout-path and SPCR\r
206 //\r
207 Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, &Gop);\r
208 if (EFI_ERROR (Status)) {\r
209 DEBUG ((DEBUG_INFO,\r
210 "%a: no GOP instances found - doing nothing (%r)\n", __FUNCTION__,\r
211 Status));\r
212 return;\r
213 }\r
214\r
215 RemoveDtStdoutPath ();\r
216 RemoveSpcrTable ();\r
217}\r
218\r
219/**\r
220 The entry point for ConsolePrefDxe driver.\r
221\r
222 @param[in] ImageHandle The image handle of the driver.\r
223 @param[in] SystemTable The system table.\r
224\r
225 @retval EFI_ALREADY_STARTED The driver already exists in system.\r
226 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of\r
227 resources.\r
c6a72cd7 228 @retval EFI_SUCCESS All the related protocols are installed on\r
d8e36289
AB
229 the driver.\r
230\r
231**/\r
232EFI_STATUS\r
233EFIAPI\r
234ConsolePrefDxeEntryPoint (\r
235 IN EFI_HANDLE ImageHandle,\r
236 IN EFI_SYSTEM_TABLE *SystemTable\r
237 )\r
238{\r
239 EFI_STATUS Status;\r
240 CONSOLE_PREF_VARSTORE_DATA ConsolePref;\r
241 UINTN BufferSize;\r
242\r
243 //\r
244 // Get the current console preference from the ConsolePref variable.\r
245 //\r
246 BufferSize = sizeof (ConsolePref);\r
247 Status = gRT->GetVariable (CONSOLE_PREF_VARIABLE_NAME,\r
248 &gConsolePrefFormSetGuid, NULL, &BufferSize, &ConsolePref);\r
249 if (EFI_ERROR (Status)) {\r
250 DEBUG ((DEBUG_INFO,\r
251 "%a: no console preference found, defaulting to graphical\n",\r
252 __FUNCTION__));\r
253 ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;\r
254 }\r
255\r
256 if (!EFI_ERROR (Status) &&\r
257 ConsolePref.Console != CONSOLE_PREF_GRAPHICAL &&\r
258 ConsolePref.Console != CONSOLE_PREF_SERIAL) {\r
259 DEBUG ((DEBUG_WARN, "%a: invalid value for %s, defaulting to graphical\n",\r
260 __FUNCTION__, CONSOLE_PREF_VARIABLE_NAME));\r
261 ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;\r
262 Status = EFI_INVALID_PARAMETER; // trigger setvar below\r
263 }\r
264\r
265 //\r
266 // Write the newly selected value back to the variable store.\r
267 //\r
268 if (EFI_ERROR (Status)) {\r
269 ZeroMem (&ConsolePref.Reserved, sizeof (ConsolePref.Reserved));\r
270 Status = gRT->SetVariable (CONSOLE_PREF_VARIABLE_NAME,\r
271 &gConsolePrefFormSetGuid,\r
272 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
273 sizeof (ConsolePref), &ConsolePref);\r
274\r
275 if (EFI_ERROR (Status)) {\r
276 DEBUG ((DEBUG_ERROR, "%a: gRT->SetVariable () failed - %r\n",\r
277 __FUNCTION__, Status));\r
278 return Status;\r
279 }\r
280 }\r
281\r
282 Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,\r
283 OnReadyToBoot, NULL, &gEfiEventReadyToBootGuid,\r
284 &mReadyToBootEvent);\r
285 ASSERT_EFI_ERROR (Status);\r
286\r
287 return InstallHiiPages ();\r
288}\r