]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c
CorebootPayloadPkg: Fix typos in comments
[mirror_edk2.git] / CorebootPayloadPkg / Library / PlatformBootManagerLib / PlatformConsole.c
CommitLineData
42a8f2ce
MM
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
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "PlatformBootManager.h"\r
16#include "PlatformConsole.h"\r
17\r
18#define PCI_DEVICE_PATH_NODE(Func, Dev) \\r
19 { \\r
20 { \\r
21 HARDWARE_DEVICE_PATH, \\r
22 HW_PCI_DP, \\r
23 { \\r
24 (UINT8) (sizeof (PCI_DEVICE_PATH)), \\r
25 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \\r
26 } \\r
27 }, \\r
28 (Func), \\r
29 (Dev) \\r
30 }\r
31\r
32#define PNPID_DEVICE_PATH_NODE(PnpId) \\r
33 { \\r
34 { \\r
35 ACPI_DEVICE_PATH, \\r
36 ACPI_DP, \\r
37 { \\r
38 (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \\r
39 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \\r
40 }, \\r
41 }, \\r
42 EISA_PNP_ID((PnpId)), \\r
43 0 \\r
44 }\r
45\r
46#define gPciRootBridge \\r
47 PNPID_DEVICE_PATH_NODE(0x0A03)\r
48\r
49#define gPnp16550ComPort \\r
50 PNPID_DEVICE_PATH_NODE(0x0501)\r
51\r
52#define gUartVendor \\r
53 { \\r
54 { \\r
55 HARDWARE_DEVICE_PATH, \\r
56 HW_VENDOR_DP, \\r
57 { \\r
58 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \\r
59 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \\r
60 } \\r
61 }, \\r
62 {0xD3987D4B, 0x971A, 0x435F, {0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41}} \\r
63 }\r
64\r
65#define gUart \\r
66 { \\r
67 { \\r
68 MESSAGING_DEVICE_PATH, \\r
69 MSG_UART_DP, \\r
70 { \\r
71 (UINT8) (sizeof (UART_DEVICE_PATH)), \\r
72 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \\r
73 } \\r
74 }, \\r
75 0, \\r
76 115200, \\r
77 8, \\r
78 1, \\r
79 1 \\r
80 }\r
81\r
82#define gPcAnsiTerminal \\r
83 { \\r
84 { \\r
85 MESSAGING_DEVICE_PATH, \\r
86 MSG_VENDOR_DP, \\r
87 { \\r
88 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \\r
89 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \\r
90 } \\r
91 }, \\r
92 DEVICE_PATH_MESSAGING_PC_ANSI \\r
93 }\r
94\r
95\r
96ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;\r
97UART_DEVICE_PATH gUartDeviceNode = gUart;\r
98VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;\r
99VENDOR_DEVICE_PATH gUartDeviceVendorNode = gUartVendor;\r
100\r
101//\r
102// Predefined platform root bridge\r
103//\r
104PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {\r
105 gPciRootBridge,\r
106 gEndEntire\r
107};\r
108\r
109EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges[] = {\r
110 (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0,\r
111 NULL\r
112};\r
113\r
114BOOLEAN mDetectVgaOnly;\r
115\r
116/**\r
117 Add UART to ConOut, ConIn, ErrOut.\r
118\r
119 @param[in] DeviceHandle - LPC device path.\r
120\r
121 @retval EFI_SUCCESS - Serial console is added to ConOut, ConIn, and ErrOut.\r
122 @retval EFI_STATUS - No serial console is added.\r
123**/\r
124EFI_STATUS\r
125PrepareLpcBridgeDevicePath (\r
126 IN EFI_HANDLE DeviceHandle\r
127)\r
128{\r
129 EFI_STATUS Status;\r
130 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
131\r
132 DevicePath = NULL;\r
133 Status = gBS->HandleProtocol (\r
134 DeviceHandle,\r
135 &gEfiDevicePathProtocolGuid,\r
136 (VOID*)&DevicePath\r
137 );\r
138 if (EFI_ERROR (Status)) {\r
139 return Status;\r
140 }\r
141\r
142 //\r
143 // Register COM1\r
144 //\r
145 DevicePath = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)NULL, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceVendorNode);\r
146 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
147 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
148\r
149 EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
150 EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
151 EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
152\r
153 return EFI_SUCCESS;\r
154}\r
155\r
156/**\r
157 Return the GOP device path in the platform.\r
158\r
159 @param[in] PciDevicePath - Device path for the PCI graphics device.\r
160 @param[out] GopDevicePath - Return the device path with GOP installed.\r
161\r
162 @retval EFI_SUCCESS - PCI VGA is added to ConOut.\r
163 @retval EFI_INVALID_PARAMETER - The device path parameter is invalid.\r
164 @retval EFI_STATUS - No GOP device found.\r
165**/\r
166EFI_STATUS\r
167GetGopDevicePath (\r
168 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
169 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
170)\r
171{\r
172 UINTN Index;\r
173 EFI_STATUS Status;\r
174 EFI_HANDLE PciDeviceHandle;\r
175 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
176 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
177 UINTN GopHandleCount;\r
178 EFI_HANDLE *GopHandleBuffer;\r
179 ACPI_ADR_DEVICE_PATH AcpiAdr;\r
180 EFI_DEVICE_PATH_PROTOCOL *MyDevicePath;\r
181\r
182 if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
183 return EFI_INVALID_PARAMETER;\r
184 }\r
185\r
186 MyDevicePath = NULL;\r
187\r
188 //\r
189 // Initialize the GopDevicePath to be PciDevicePath\r
190 //\r
191 *GopDevicePath = PciDevicePath;\r
192 TempPciDevicePath = PciDevicePath;\r
193\r
194 Status = gBS->LocateDevicePath (\r
195 &gEfiDevicePathProtocolGuid,\r
196 &TempPciDevicePath,\r
197 &PciDeviceHandle\r
198 );\r
199 if (EFI_ERROR (Status)) {\r
200 return Status;\r
201 }\r
202\r
203 //\r
e7700ced 204 // Try to connect this handle, so that GOP driver could start on this\r
42a8f2ce
MM
205 // device and create child handles with GraphicsOutput Protocol installed\r
206 // on them, then we get device paths of these child handles and select\r
207 // them as possible console device.\r
208 //\r
209 AcpiAdr.Header.Type = ACPI_DEVICE_PATH;\r
210 AcpiAdr.Header.SubType = ACPI_ADR_DP;\r
211 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, 8, 0);\r
212\r
213 SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
214\r
215 MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);\r
216\r
217 gBS->ConnectController (PciDeviceHandle, NULL, MyDevicePath, FALSE);\r
218\r
219 FreePool(MyDevicePath);\r
220\r
221 Status = gBS->LocateHandleBuffer (\r
222 ByProtocol,\r
223 &gEfiGraphicsOutputProtocolGuid,\r
224 NULL,\r
225 &GopHandleCount,\r
226 &GopHandleBuffer\r
227 );\r
228 if (!EFI_ERROR (Status)) {\r
229 //\r
230 // Add all the child handles as possible Console Device\r
231 //\r
232 for (Index = 0; Index < GopHandleCount; Index++) {\r
233 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
234 if (EFI_ERROR (Status)) {\r
235 continue;\r
236 }\r
237 if (CompareMem (\r
238 PciDevicePath,\r
239 TempDevicePath,\r
240 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
241 ) == 0) {\r
242 //\r
243 // In current implementation, we only enable one of the child handles\r
244 // as console device, i.e. sotre one of the child handle's device\r
245 // path to variable "ConOut"\r
e7700ced 246 // In future, we could select all child handles to be console device\r
42a8f2ce
MM
247 //\r
248 *GopDevicePath = TempDevicePath;\r
249\r
250 //\r
251 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
252 // Add the integrity GOP device path.\r
253 //\r
254 EfiBootManagerUpdateConsoleVariable (ConOut, NULL, PciDevicePath);\r
255 EfiBootManagerUpdateConsoleVariable (ConOut, TempDevicePath, NULL);\r
256 }\r
257 }\r
258 gBS->FreePool (GopHandleBuffer);\r
259 }\r
260\r
261 return EFI_SUCCESS;\r
262}\r
263\r
264/**\r
265 Add PCI VGA to ConOut, ConIn, ErrOut.\r
266\r
267 @param[in] DeviceHandle - Handle of PciIo protocol.\r
268\r
269 @retval EFI_SUCCESS - PCI VGA is added to ConOut.\r
270 @retval EFI_STATUS - No PCI VGA device is added.\r
271\r
272**/\r
273EFI_STATUS\r
274PreparePciVgaDevicePath (\r
275 IN EFI_HANDLE DeviceHandle\r
276)\r
277{\r
278 EFI_STATUS Status;\r
279 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
280 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
281\r
282 DevicePath = NULL;\r
283 Status = gBS->HandleProtocol (\r
284 DeviceHandle,\r
285 &gEfiDevicePathProtocolGuid,\r
286 (VOID*)&DevicePath\r
287 );\r
288 if (EFI_ERROR (Status)) {\r
289 return Status;\r
290 }\r
291\r
292 GetGopDevicePath (DevicePath, &GopDevicePath);\r
293 DevicePath = GopDevicePath;\r
294\r
295 EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
296\r
297 return EFI_SUCCESS;\r
298}\r
299\r
300/**\r
301 Add PCI Serial to ConOut, ConIn, ErrOut.\r
302\r
303 @param[in] DeviceHandle - Handle of PciIo protocol.\r
304\r
305 @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
306 @retval EFI_STATUS - No PCI Serial device is added.\r
307\r
308**/\r
309EFI_STATUS\r
310PreparePciSerialDevicePath (\r
311 IN EFI_HANDLE DeviceHandle\r
312)\r
313{\r
314 EFI_STATUS Status;\r
315 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
316\r
317 DevicePath = NULL;\r
318 Status = gBS->HandleProtocol (\r
319 DeviceHandle,\r
320 &gEfiDevicePathProtocolGuid,\r
321 (VOID*)&DevicePath\r
322 );\r
323 if (EFI_ERROR (Status)) {\r
324 return Status;\r
325 }\r
326\r
327 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
328 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
329\r
330 EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
331 EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
332 EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
333\r
334 return EFI_SUCCESS;\r
335}\r
336\r
337\r
338/**\r
339 For every PCI instance execute a callback function.\r
340\r
341 @param[in] Id - The protocol GUID for callback\r
342 @param[in] CallBackFunction - The callback function\r
343 @param[in] Context - The context of the callback\r
344\r
345 @retval EFI_STATUS - Callback function failed.\r
346\r
347**/\r
348EFI_STATUS\r
349EFIAPI\r
350VisitAllInstancesOfProtocol (\r
351 IN EFI_GUID *Id,\r
352 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
353 IN VOID *Context\r
354)\r
355{\r
356 EFI_STATUS Status;\r
357 UINTN HandleCount;\r
358 EFI_HANDLE *HandleBuffer;\r
359 UINTN Index;\r
360 VOID *Instance;\r
361\r
362 //\r
363 // Start to check all the PciIo to find all possible device\r
364 //\r
365 HandleCount = 0;\r
366 HandleBuffer = NULL;\r
367 Status = gBS->LocateHandleBuffer (\r
368 ByProtocol,\r
369 Id,\r
370 NULL,\r
371 &HandleCount,\r
372 &HandleBuffer\r
373 );\r
374 if (EFI_ERROR (Status)) {\r
375 return Status;\r
376 }\r
377\r
378 for (Index = 0; Index < HandleCount; Index++) {\r
379 Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
380 if (EFI_ERROR (Status)) {\r
381 continue;\r
382 }\r
383\r
384 Status = (*CallBackFunction) (\r
385 HandleBuffer[Index],\r
386 Instance,\r
387 Context\r
388 );\r
389 }\r
390\r
391 gBS->FreePool (HandleBuffer);\r
392\r
393 return EFI_SUCCESS;\r
394}\r
395\r
396\r
397/**\r
398 For every PCI instance execute a callback function.\r
399\r
400 @param[in] Handle - The PCI device handle\r
401 @param[in] Instance - The instance of the PciIo protocol\r
402 @param[in] Context - The context of the callback\r
403\r
404 @retval EFI_STATUS - Callback function failed.\r
405\r
406**/\r
407EFI_STATUS\r
408EFIAPI\r
409VisitingAPciInstance (\r
410 IN EFI_HANDLE Handle,\r
411 IN VOID *Instance,\r
412 IN VOID *Context\r
413)\r
414{\r
415 EFI_STATUS Status;\r
416 EFI_PCI_IO_PROTOCOL *PciIo;\r
417 PCI_TYPE00 Pci;\r
418\r
419 PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
420\r
421 //\r
422 // Check for all PCI device\r
423 //\r
424 Status = PciIo->Pci.Read (\r
425 PciIo,\r
426 EfiPciIoWidthUint32,\r
427 0,\r
428 sizeof (Pci) / sizeof (UINT32),\r
429 &Pci\r
430 );\r
431 if (EFI_ERROR (Status)) {\r
432 return Status;\r
433 }\r
434\r
435 return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
436 Handle,\r
437 PciIo,\r
438 &Pci\r
439 );\r
440\r
441}\r
442\r
443\r
444/**\r
445 For every PCI instance execute a callback function.\r
446\r
447 @param[in] CallBackFunction - Callback function pointer\r
448\r
449 @retval EFI_STATUS - Callback function failed.\r
450\r
451**/\r
452EFI_STATUS\r
453EFIAPI\r
454VisitAllPciInstances (\r
455 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
456)\r
457{\r
458 return VisitAllInstancesOfProtocol (\r
459 &gEfiPciIoProtocolGuid,\r
460 VisitingAPciInstance,\r
461 (VOID*)(UINTN) CallBackFunction\r
462 );\r
463}\r
464\r
465\r
466/**\r
467 Do platform specific PCI Device check and add them to\r
468 ConOut, ConIn, ErrOut.\r
469\r
470 @param[in] Handle - Handle of PCI device instance\r
471 @param[in] PciIo - PCI IO protocol instance\r
472 @param[in] Pci - PCI Header register block\r
473\r
474 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
475 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
476\r
477**/\r
478EFI_STATUS\r
479EFIAPI\r
480DetectAndPreparePlatformPciDevicePath (\r
481 IN EFI_HANDLE Handle,\r
482 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
483 IN PCI_TYPE00 *Pci\r
484)\r
485{\r
486 EFI_STATUS Status;\r
487\r
488 Status = PciIo->Attributes (\r
489 PciIo,\r
490 EfiPciIoAttributeOperationEnable,\r
491 EFI_PCI_DEVICE_ENABLE,\r
492 NULL\r
493 );\r
494 ASSERT_EFI_ERROR (Status);\r
495\r
496 if (!mDetectVgaOnly) {\r
497 //\r
498 // Here we decide whether it is LPC Bridge\r
499 //\r
500 if ((IS_PCI_LPC (Pci)) ||\r
501 ((IS_PCI_ISA_PDECODE (Pci)) &&\r
502 (Pci->Hdr.VendorId == 0x8086)\r
503 )\r
504 ) {\r
505 //\r
506 // Add IsaKeyboard to ConIn,\r
507 // add IsaSerial to ConOut, ConIn, ErrOut\r
508 //\r
509 DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
510 PrepareLpcBridgeDevicePath (Handle);\r
511 return EFI_SUCCESS;\r
512 }\r
513 //\r
514 // Here we decide which Serial device to enable in PCI bus\r
515 //\r
516 if (IS_PCI_16550SERIAL (Pci)) {\r
517 //\r
518 // Add them to ConOut, ConIn, ErrOut.\r
519 //\r
520 DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
521 PreparePciSerialDevicePath (Handle);\r
522 return EFI_SUCCESS;\r
523 }\r
524 }\r
525\r
526 //\r
527 // Here we decide which VGA device to enable in PCI bus\r
528 //\r
529 if (IS_PCI_VGA (Pci)) {\r
530 //\r
531 // Add them to ConOut.\r
532 //\r
533 DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
534 PreparePciVgaDevicePath (Handle);\r
535 return EFI_SUCCESS;\r
536 }\r
537\r
538 return Status;\r
539}\r
540\r
541\r
542/**\r
543 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
544\r
545 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
546\r
547 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
548 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
549\r
550**/\r
551EFI_STATUS\r
552DetectAndPreparePlatformPciDevicePaths (\r
553 BOOLEAN DetectVgaOnly\r
554)\r
555{\r
556 mDetectVgaOnly = DetectVgaOnly;\r
557 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
558}\r
559\r
560\r
561/**\r
562 The function will connect root bridge\r
563\r
564 @return EFI_SUCCESS Connect RootBridge successfully.\r
565\r
566**/\r
567EFI_STATUS\r
568ConnectRootBridge (\r
569 VOID\r
570)\r
571{\r
572 EFI_STATUS Status;\r
573 EFI_HANDLE RootHandle;\r
574\r
575 //\r
576 // Make all the PCI_IO protocols on PCI Seg 0 show up\r
577 //\r
578 Status = gBS->LocateDevicePath (\r
579 &gEfiDevicePathProtocolGuid,\r
580 &gPlatformRootBridges[0],\r
581 &RootHandle\r
582 );\r
583 if (EFI_ERROR (Status)) {\r
584 return Status;\r
585 }\r
586\r
587 Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);\r
588 if (EFI_ERROR (Status)) {\r
589 return Status;\r
590 }\r
591\r
592 return EFI_SUCCESS;\r
593}\r
594\r
595/**\r
596 Platform console init. Include the platform firmware vendor, revision\r
597 and so crc check.\r
598\r
599**/\r
600VOID\r
601EFIAPI\r
602PlatformConsoleInit (\r
603 VOID\r
604)\r
605{\r
606 gUartDeviceNode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
607 gUartDeviceNode.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
608 gUartDeviceNode.Parity = PcdGet8 (PcdUartDefaultParity);\r
609 gUartDeviceNode.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
610\r
611 ConnectRootBridge ();\r
612\r
613 //\r
614 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
615 //\r
616 DetectAndPreparePlatformPciDevicePaths (FALSE);\r
617}\r