]> git.proxmox.com Git - mirror_edk2.git/blame - UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiPayloadPkg / Library / PlatformBootManagerLib / PlatformConsole.c
CommitLineData
04af8bf2
DG
1/** @file\r
2This file include all platform action which can be customized by IBV/OEM.\r
3\r
4Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "PlatformBootManager.h"\r
10#include "PlatformConsole.h"\r
fec63bb9 11#include <Guid/SerialPortLibVendor.h>\r
04af8bf2
DG
12\r
13#define PCI_DEVICE_PATH_NODE(Func, Dev) \\r
14 { \\r
15 { \\r
16 HARDWARE_DEVICE_PATH, \\r
17 HW_PCI_DP, \\r
18 { \\r
19 (UINT8) (sizeof (PCI_DEVICE_PATH)), \\r
20 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \\r
21 } \\r
22 }, \\r
23 (Func), \\r
24 (Dev) \\r
25 }\r
26\r
27#define PNPID_DEVICE_PATH_NODE(PnpId) \\r
28 { \\r
29 { \\r
30 ACPI_DEVICE_PATH, \\r
31 ACPI_DP, \\r
32 { \\r
33 (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \\r
34 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \\r
35 }, \\r
36 }, \\r
37 EISA_PNP_ID((PnpId)), \\r
38 0 \\r
39 }\r
40\r
04af8bf2
DG
41#define gPnp16550ComPort \\r
42 PNPID_DEVICE_PATH_NODE(0x0501)\r
43\r
33a32936
DG
44#define gPnpPs2Keyboard \\r
45 PNPID_DEVICE_PATH_NODE(0x0303)\r
46\r
04af8bf2
DG
47#define gPcAnsiTerminal \\r
48 { \\r
49 { \\r
50 MESSAGING_DEVICE_PATH, \\r
51 MSG_VENDOR_DP, \\r
52 { \\r
53 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \\r
54 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \\r
55 } \\r
56 }, \\r
57 DEVICE_PATH_MESSAGING_PC_ANSI \\r
58 }\r
59\r
e5efcf8b
MK
60ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;\r
61ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;\r
e5efcf8b 62VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;\r
04af8bf2 63\r
2b4b8013 64BOOLEAN mDetectDisplayOnly;\r
04af8bf2
DG
65\r
66/**\r
57ebb299 67 Add IsaKeyboard to ConIn.\r
04af8bf2 68\r
33a32936 69 @param[in] DeviceHandle Handle of the LPC Bridge device.\r
04af8bf2 70\r
57ebb299 71 @retval EFI_SUCCESS IsaKeyboard on the LPC bridge have been added to ConIn.\r
33a32936
DG
72 @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
73 from DeviceHandle.\r
04af8bf2
DG
74**/\r
75EFI_STATUS\r
76PrepareLpcBridgeDevicePath (\r
e5efcf8b
MK
77 IN EFI_HANDLE DeviceHandle\r
78 )\r
04af8bf2
DG
79{\r
80 EFI_STATUS Status;\r
81 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
82\r
83 DevicePath = NULL;\r
e5efcf8b
MK
84 Status = gBS->HandleProtocol (\r
85 DeviceHandle,\r
86 &gEfiDevicePathProtocolGuid,\r
87 (VOID *)&DevicePath\r
88 );\r
04af8bf2
DG
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
e5efcf8b 92\r
33a32936
DG
93 //\r
94 // Register Keyboard\r
95 //\r
96 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
97 EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
04af8bf2
DG
98 return EFI_SUCCESS;\r
99}\r
100\r
101/**\r
102 Return the GOP device path in the platform.\r
103\r
104 @param[in] PciDevicePath - Device path for the PCI graphics device.\r
105 @param[out] GopDevicePath - Return the device path with GOP installed.\r
106\r
107 @retval EFI_SUCCESS - PCI VGA is added to ConOut.\r
108 @retval EFI_INVALID_PARAMETER - The device path parameter is invalid.\r
109 @retval EFI_STATUS - No GOP device found.\r
110**/\r
111EFI_STATUS\r
112GetGopDevicePath (\r
e5efcf8b
MK
113 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
114 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
115 )\r
04af8bf2 116{\r
e5efcf8b
MK
117 UINTN Index;\r
118 EFI_STATUS Status;\r
119 EFI_HANDLE PciDeviceHandle;\r
120 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
121 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
122 UINTN GopHandleCount;\r
123 EFI_HANDLE *GopHandleBuffer;\r
124\r
125 if ((PciDevicePath == NULL) || (GopDevicePath == NULL)) {\r
04af8bf2
DG
126 return EFI_INVALID_PARAMETER;\r
127 }\r
128\r
129 //\r
130 // Initialize the GopDevicePath to be PciDevicePath\r
131 //\r
132 *GopDevicePath = PciDevicePath;\r
133 TempPciDevicePath = PciDevicePath;\r
134\r
135 Status = gBS->LocateDevicePath (\r
e5efcf8b
MK
136 &gEfiDevicePathProtocolGuid,\r
137 &TempPciDevicePath,\r
138 &PciDeviceHandle\r
139 );\r
04af8bf2
DG
140 if (EFI_ERROR (Status)) {\r
141 return Status;\r
142 }\r
143\r
144 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
145\r
146 Status = gBS->LocateHandleBuffer (\r
e5efcf8b
MK
147 ByProtocol,\r
148 &gEfiGraphicsOutputProtocolGuid,\r
149 NULL,\r
150 &GopHandleCount,\r
151 &GopHandleBuffer\r
152 );\r
04af8bf2
DG
153 if (!EFI_ERROR (Status)) {\r
154 //\r
155 // Add all the child handles as possible Console Device\r
156 //\r
157 for (Index = 0; Index < GopHandleCount; Index++) {\r
e5efcf8b 158 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *)&TempDevicePath);\r
04af8bf2
DG
159 if (EFI_ERROR (Status)) {\r
160 continue;\r
161 }\r
e5efcf8b 162\r
04af8bf2
DG
163 if (CompareMem (\r
164 PciDevicePath,\r
165 TempDevicePath,\r
166 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
e5efcf8b
MK
167 ) == 0)\r
168 {\r
04af8bf2
DG
169 //\r
170 // In current implementation, we only enable one of the child handles\r
171 // as console device, i.e. sotre one of the child handle's device\r
172 // path to variable "ConOut"\r
173 // In future, we could select all child handles to be console device\r
174 //\r
175 *GopDevicePath = TempDevicePath;\r
176\r
177 //\r
178 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
179 // Add the integrity GOP device path.\r
180 //\r
181 EfiBootManagerUpdateConsoleVariable (ConOut, NULL, PciDevicePath);\r
182 EfiBootManagerUpdateConsoleVariable (ConOut, TempDevicePath, NULL);\r
183 }\r
184 }\r
e5efcf8b 185\r
04af8bf2
DG
186 gBS->FreePool (GopHandleBuffer);\r
187 }\r
188\r
189 return EFI_SUCCESS;\r
190}\r
191\r
192/**\r
193 Add PCI VGA to ConOut, ConIn, ErrOut.\r
194\r
195 @param[in] DeviceHandle - Handle of PciIo protocol.\r
196\r
197 @retval EFI_SUCCESS - PCI VGA is added to ConOut.\r
198 @retval EFI_STATUS - No PCI VGA device is added.\r
199\r
200**/\r
201EFI_STATUS\r
202PreparePciVgaDevicePath (\r
e5efcf8b
MK
203 IN EFI_HANDLE DeviceHandle\r
204 )\r
04af8bf2
DG
205{\r
206 EFI_STATUS Status;\r
207 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
208 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
209\r
210 DevicePath = NULL;\r
e5efcf8b
MK
211 Status = gBS->HandleProtocol (\r
212 DeviceHandle,\r
213 &gEfiDevicePathProtocolGuid,\r
214 (VOID *)&DevicePath\r
215 );\r
04af8bf2
DG
216 if (EFI_ERROR (Status)) {\r
217 return Status;\r
218 }\r
219\r
220 GetGopDevicePath (DevicePath, &GopDevicePath);\r
221 DevicePath = GopDevicePath;\r
222\r
223 EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
224\r
225 return EFI_SUCCESS;\r
226}\r
227\r
04af8bf2
DG
228/**\r
229 For every PCI instance execute a callback function.\r
230\r
231 @param[in] Id - The protocol GUID for callback\r
232 @param[in] CallBackFunction - The callback function\r
04af8bf2
DG
233\r
234 @retval EFI_STATUS - Callback function failed.\r
235\r
236**/\r
237EFI_STATUS\r
238EFIAPI\r
239VisitAllInstancesOfProtocol (\r
d0efa681
ZL
240 IN EFI_GUID *Id,\r
241 IN SIMPLE_PROTOCOL_INSTANCE_CALLBACK CallBackFunction\r
e5efcf8b 242 )\r
04af8bf2 243{\r
e5efcf8b
MK
244 EFI_STATUS Status;\r
245 UINTN HandleCount;\r
246 EFI_HANDLE *HandleBuffer;\r
247 UINTN Index;\r
248 VOID *Instance;\r
04af8bf2
DG
249\r
250 //\r
251 // Start to check all the PciIo to find all possible device\r
252 //\r
e5efcf8b 253 HandleCount = 0;\r
04af8bf2 254 HandleBuffer = NULL;\r
e5efcf8b
MK
255 Status = gBS->LocateHandleBuffer (\r
256 ByProtocol,\r
257 Id,\r
258 NULL,\r
259 &HandleCount,\r
260 &HandleBuffer\r
261 );\r
04af8bf2
DG
262 if (EFI_ERROR (Status)) {\r
263 return Status;\r
264 }\r
265\r
266 for (Index = 0; Index < HandleCount; Index++) {\r
267 Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
268 if (EFI_ERROR (Status)) {\r
269 continue;\r
270 }\r
271\r
e5efcf8b
MK
272 Status = (*CallBackFunction)(\r
273 HandleBuffer[Index],\r
d0efa681 274 Instance\r
e5efcf8b 275 );\r
04af8bf2
DG
276 }\r
277\r
278 gBS->FreePool (HandleBuffer);\r
279\r
280 return EFI_SUCCESS;\r
281}\r
282\r
04af8bf2 283/**\r
d0efa681
ZL
284 Do platform specific PCI Device check and add them to\r
285 ConOut, ConIn, ErrOut.\r
04af8bf2 286\r
d0efa681
ZL
287 @param[in] Handle - Handle of PCI device instance\r
288 @param[in] Instance - The instance of PCI device\r
04af8bf2 289\r
d0efa681
ZL
290 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
291 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
04af8bf2
DG
292\r
293**/\r
294EFI_STATUS\r
295EFIAPI\r
d0efa681 296DetectAndPreparePlatformPciDevicePath (\r
04af8bf2 297 IN EFI_HANDLE Handle,\r
d0efa681 298 IN VOID *Instance\r
e5efcf8b 299 )\r
04af8bf2 300{\r
e5efcf8b
MK
301 EFI_STATUS Status;\r
302 EFI_PCI_IO_PROTOCOL *PciIo;\r
303 PCI_TYPE00 Pci;\r
04af8bf2 304\r
e5efcf8b 305 PciIo = (EFI_PCI_IO_PROTOCOL *)Instance;\r
04af8bf2
DG
306\r
307 //\r
308 // Check for all PCI device\r
309 //\r
310 Status = PciIo->Pci.Read (\r
e5efcf8b
MK
311 PciIo,\r
312 EfiPciIoWidthUint32,\r
313 0,\r
314 sizeof (Pci) / sizeof (UINT32),\r
315 &Pci\r
316 );\r
04af8bf2
DG
317 if (EFI_ERROR (Status)) {\r
318 return Status;\r
319 }\r
320\r
04af8bf2 321 Status = PciIo->Attributes (\r
e5efcf8b
MK
322 PciIo,\r
323 EfiPciIoAttributeOperationEnable,\r
324 EFI_PCI_DEVICE_ENABLE,\r
325 NULL\r
326 );\r
04af8bf2
DG
327 ASSERT_EFI_ERROR (Status);\r
328\r
2b4b8013 329 if (!mDetectDisplayOnly) {\r
04af8bf2
DG
330 //\r
331 // Here we decide whether it is LPC Bridge\r
332 //\r
d0efa681
ZL
333 if ((IS_PCI_LPC (&Pci)) ||\r
334 ((IS_PCI_ISA_PDECODE (&Pci)) &&\r
335 (Pci.Hdr.VendorId == 0x8086)\r
04af8bf2 336 )\r
e5efcf8b
MK
337 )\r
338 {\r
04af8bf2
DG
339 //\r
340 // Add IsaKeyboard to ConIn,\r
341 // add IsaSerial to ConOut, ConIn, ErrOut\r
342 //\r
343 DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n"));\r
344 PrepareLpcBridgeDevicePath (Handle);\r
345 return EFI_SUCCESS;\r
346 }\r
04af8bf2
DG
347 }\r
348\r
349 //\r
2b4b8013 350 // Enable all display devices\r
04af8bf2 351 //\r
d0efa681 352 if (IS_PCI_DISPLAY (&Pci)) {\r
04af8bf2
DG
353 //\r
354 // Add them to ConOut.\r
355 //\r
2b4b8013
PR
356 DEBUG ((DEBUG_INFO, "Found PCI Display device\n"));\r
357 EfiBootManagerConnectVideoController (Handle);\r
04af8bf2
DG
358 return EFI_SUCCESS;\r
359 }\r
360\r
361 return Status;\r
362}\r
363\r
57ebb299
ZL
364/**\r
365 For every Serial Io instance, add it to ConOut, ConIn, ErrOut.\r
366\r
367 @param[in] Handle - The Serial Io device handle\r
368 @param[in] Instance - The instance of the SerialIo protocol\r
369\r
370 @retval EFI_STATUS - Callback function failed.\r
371\r
372**/\r
373EFI_STATUS\r
374EFIAPI\r
375AddDevicePathForOneSerialIoInstance (\r
376 IN EFI_HANDLE Handle,\r
377 IN VOID *Instance\r
378 )\r
379{\r
380 EFI_STATUS Status;\r
381 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
382\r
383 DevicePath = NULL;\r
384 Status = gBS->HandleProtocol (\r
385 Handle,\r
386 &gEfiDevicePathProtocolGuid,\r
387 (VOID *)&DevicePath\r
388 );\r
389 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
390\r
391 EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
392 EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
393 EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
394 return Status;\r
395}\r
396\r
04af8bf2
DG
397/**\r
398 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
399\r
2b4b8013 400 @param[in] DetectDisplayOnly - Only detect display device if it's TRUE.\r
04af8bf2
DG
401\r
402 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
403 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
404\r
405**/\r
406EFI_STATUS\r
407DetectAndPreparePlatformPciDevicePaths (\r
2b4b8013 408 BOOLEAN DetectDisplayOnly\r
e5efcf8b 409 )\r
04af8bf2 410{\r
d0efa681
ZL
411 EFI_STATUS Status;\r
412\r
2b4b8013 413 mDetectDisplayOnly = DetectDisplayOnly;\r
04af8bf2
DG
414\r
415 EfiBootManagerUpdateConsoleVariable (\r
416 ConIn,\r
e5efcf8b 417 (EFI_DEVICE_PATH_PROTOCOL *)&gUsbClassKeyboardDevicePath,\r
04af8bf2
DG
418 NULL\r
419 );\r
420\r
57ebb299
ZL
421 VisitAllInstancesOfProtocol (\r
422 &gEfiSerialIoProtocolGuid,\r
423 AddDevicePathForOneSerialIoInstance\r
424 );\r
425\r
d0efa681
ZL
426 Status = VisitAllInstancesOfProtocol (\r
427 &gEfiPciIoProtocolGuid,\r
428 DetectAndPreparePlatformPciDevicePath\r
429 );\r
430 return Status;\r
04af8bf2
DG
431}\r
432\r
04af8bf2 433/**\r
ef01d63e 434 The function will connect one root bridge\r
04af8bf2 435\r
ef01d63e
ZL
436 @param[in] Handle - The root bridge handle\r
437 @param[in] Instance - The instance of the root bridge\r
438\r
439 @return EFI_SUCCESS Connect RootBridge successfully.\r
04af8bf2
DG
440\r
441**/\r
442EFI_STATUS\r
ef01d63e
ZL
443EFIAPI\r
444ConnectOneRootBridge (\r
445 IN EFI_HANDLE Handle,\r
446 IN VOID *Instance\r
e5efcf8b 447 )\r
04af8bf2 448{\r
e5efcf8b 449 EFI_STATUS Status;\r
04af8bf2 450\r
ef01d63e 451 Status = gBS->ConnectController (Handle, NULL, NULL, FALSE);\r
04af8bf2
DG
452 if (EFI_ERROR (Status)) {\r
453 return Status;\r
454 }\r
455\r
456 return EFI_SUCCESS;\r
457}\r
458\r
459/**\r
460 Platform console init. Include the platform firmware vendor, revision\r
461 and so crc check.\r
462\r
463**/\r
464VOID\r
465EFIAPI\r
466PlatformConsoleInit (\r
467 VOID\r
e5efcf8b 468 )\r
04af8bf2 469{\r
ef01d63e
ZL
470 VisitAllInstancesOfProtocol (\r
471 &gEfiPciRootBridgeIoProtocolGuid,\r
472 ConnectOneRootBridge\r
473 );\r
04af8bf2
DG
474\r
475 //\r
476 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
477 //\r
478 DetectAndPreparePlatformPciDevicePaths (FALSE);\r
04af8bf2 479}\r