VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c@ 93492

Last change on this file since 93492 was 85718, checked in by vboxsync, 5 years ago

Devices/EFI: Merge edk-stable202005 and make it build, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette