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