2 This file include all platform action which can be customized by IBV/OEM.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "PlatformBootManager.h"
10 #include "PlatformConsole.h"
11 #include <Guid/SerialPortLibVendor.h>
13 #define PCI_DEVICE_PATH_NODE(Func, Dev) \
16 HARDWARE_DEVICE_PATH, \
19 (UINT8) (sizeof (PCI_DEVICE_PATH)), \
20 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
27 #define PNPID_DEVICE_PATH_NODE(PnpId) \
33 (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
34 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
37 EISA_PNP_ID((PnpId)), \
41 #define gPciRootBridge \
42 PNPID_DEVICE_PATH_NODE(0x0A03)
44 #define gPnp16550ComPort \
45 PNPID_DEVICE_PATH_NODE(0x0501)
50 HARDWARE_DEVICE_PATH, \
53 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
54 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
57 EDKII_SERIAL_PORT_LIB_VENDOR_GUID \
63 MESSAGING_DEVICE_PATH, \
66 (UINT8) (sizeof (UART_DEVICE_PATH)), \
67 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
77 #define gPcAnsiTerminal \
80 MESSAGING_DEVICE_PATH, \
83 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
84 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
87 DEVICE_PATH_MESSAGING_PC_ANSI \
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
;
97 // Predefined platform root bridge
99 PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0
= {
104 EFI_DEVICE_PATH_PROTOCOL
*gPlatformRootBridges
[] = {
105 (EFI_DEVICE_PATH_PROTOCOL
*) &gPlatformRootBridge0
,
109 BOOLEAN mDetectVgaOnly
;
112 Add UART to ConOut, ConIn, ErrOut.
114 @param[in] DeviceHandle - LPC device path.
116 @retval EFI_SUCCESS - Serial console is added to ConOut, ConIn, and ErrOut.
117 @retval EFI_STATUS - No serial console is added.
120 PrepareLpcBridgeDevicePath (
121 IN EFI_HANDLE DeviceHandle
125 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
128 Status
= gBS
->HandleProtocol (
130 &gEfiDevicePathProtocolGuid
,
133 if (EFI_ERROR (Status
)) {
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
);
144 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
145 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
146 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
152 Return the GOP device path in the platform.
154 @param[in] PciDevicePath - Device path for the PCI graphics device.
155 @param[out] GopDevicePath - Return the device path with GOP installed.
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.
163 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
164 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
169 EFI_HANDLE PciDeviceHandle
;
170 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
171 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
172 UINTN GopHandleCount
;
173 EFI_HANDLE
*GopHandleBuffer
;
175 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
176 return EFI_INVALID_PARAMETER
;
180 // Initialize the GopDevicePath to be PciDevicePath
182 *GopDevicePath
= PciDevicePath
;
183 TempPciDevicePath
= PciDevicePath
;
185 Status
= gBS
->LocateDevicePath (
186 &gEfiDevicePathProtocolGuid
,
190 if (EFI_ERROR (Status
)) {
194 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
196 Status
= gBS
->LocateHandleBuffer (
198 &gEfiGraphicsOutputProtocolGuid
,
203 if (!EFI_ERROR (Status
)) {
205 // Add all the child handles as possible Console Device
207 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
208 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
209 if (EFI_ERROR (Status
)) {
215 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
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
223 *GopDevicePath
= TempDevicePath
;
226 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
227 // Add the integrity GOP device path.
229 EfiBootManagerUpdateConsoleVariable (ConOut
, NULL
, PciDevicePath
);
230 EfiBootManagerUpdateConsoleVariable (ConOut
, TempDevicePath
, NULL
);
233 gBS
->FreePool (GopHandleBuffer
);
240 Add PCI VGA to ConOut, ConIn, ErrOut.
242 @param[in] DeviceHandle - Handle of PciIo protocol.
244 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
245 @retval EFI_STATUS - No PCI VGA device is added.
249 PreparePciVgaDevicePath (
250 IN EFI_HANDLE DeviceHandle
254 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
255 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
258 Status
= gBS
->HandleProtocol (
260 &gEfiDevicePathProtocolGuid
,
263 if (EFI_ERROR (Status
)) {
267 GetGopDevicePath (DevicePath
, &GopDevicePath
);
268 DevicePath
= GopDevicePath
;
270 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
276 Add PCI Serial to ConOut, ConIn, ErrOut.
278 @param[in] DeviceHandle - Handle of PciIo protocol.
280 @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
281 @retval EFI_STATUS - No PCI Serial device is added.
285 PreparePciSerialDevicePath (
286 IN EFI_HANDLE DeviceHandle
290 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
293 Status
= gBS
->HandleProtocol (
295 &gEfiDevicePathProtocolGuid
,
298 if (EFI_ERROR (Status
)) {
302 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
303 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
305 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
306 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
307 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
314 For every PCI instance execute a callback function.
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
320 @retval EFI_STATUS - Callback function failed.
325 VisitAllInstancesOfProtocol (
327 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
333 EFI_HANDLE
*HandleBuffer
;
338 // Start to check all the PciIo to find all possible device
342 Status
= gBS
->LocateHandleBuffer (
349 if (EFI_ERROR (Status
)) {
353 for (Index
= 0; Index
< HandleCount
; Index
++) {
354 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
355 if (EFI_ERROR (Status
)) {
359 Status
= (*CallBackFunction
) (
366 gBS
->FreePool (HandleBuffer
);
373 For every PCI instance execute a callback function.
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
379 @retval EFI_STATUS - Callback function failed.
384 VisitingAPciInstance (
385 IN EFI_HANDLE Handle
,
391 EFI_PCI_IO_PROTOCOL
*PciIo
;
394 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
397 // Check for all PCI device
399 Status
= PciIo
->Pci
.Read (
403 sizeof (Pci
) / sizeof (UINT32
),
406 if (EFI_ERROR (Status
)) {
410 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
420 For every PCI instance execute a callback function.
422 @param[in] CallBackFunction - Callback function pointer
424 @retval EFI_STATUS - Callback function failed.
429 VisitAllPciInstances (
430 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
433 return VisitAllInstancesOfProtocol (
434 &gEfiPciIoProtocolGuid
,
435 VisitingAPciInstance
,
436 (VOID
*)(UINTN
) CallBackFunction
442 Do platform specific PCI Device check and add them to
443 ConOut, ConIn, ErrOut.
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
449 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
450 @retval EFI_STATUS - PCI Device check or Console variable update fail.
455 DetectAndPreparePlatformPciDevicePath (
456 IN EFI_HANDLE Handle
,
457 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
463 Status
= PciIo
->Attributes (
465 EfiPciIoAttributeOperationEnable
,
466 EFI_PCI_DEVICE_ENABLE
,
469 ASSERT_EFI_ERROR (Status
);
471 if (!mDetectVgaOnly
) {
473 // Here we decide whether it is LPC Bridge
475 if ((IS_PCI_LPC (Pci
)) ||
476 ((IS_PCI_ISA_PDECODE (Pci
)) &&
477 (Pci
->Hdr
.VendorId
== 0x8086)
481 // Add IsaKeyboard to ConIn,
482 // add IsaSerial to ConOut, ConIn, ErrOut
484 DEBUG ((DEBUG_INFO
, "Found LPC Bridge device\n"));
485 PrepareLpcBridgeDevicePath (Handle
);
489 // Here we decide which Serial device to enable in PCI bus
491 if (IS_PCI_16550SERIAL (Pci
)) {
493 // Add them to ConOut, ConIn, ErrOut.
495 DEBUG ((DEBUG_INFO
, "Found PCI 16550 SERIAL device\n"));
496 PreparePciSerialDevicePath (Handle
);
502 // Here we decide which VGA device to enable in PCI bus
504 if (IS_PCI_VGA (Pci
)) {
506 // Add them to ConOut.
508 DEBUG ((DEBUG_INFO
, "Found PCI VGA device\n"));
509 PreparePciVgaDevicePath (Handle
);
518 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
520 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
522 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
523 @retval EFI_STATUS - PCI Device check or Console variable update fail.
527 DetectAndPreparePlatformPciDevicePaths (
528 BOOLEAN DetectVgaOnly
531 mDetectVgaOnly
= DetectVgaOnly
;
533 EfiBootManagerUpdateConsoleVariable (
535 (EFI_DEVICE_PATH_PROTOCOL
*) &gUsbClassKeyboardDevicePath
,
539 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
544 The function will connect root bridge
546 @return EFI_SUCCESS Connect RootBridge successfully.
555 EFI_HANDLE RootHandle
;
558 // Make all the PCI_IO protocols on PCI Seg 0 show up
560 Status
= gBS
->LocateDevicePath (
561 &gEfiDevicePathProtocolGuid
,
562 &gPlatformRootBridges
[0],
565 if (EFI_ERROR (Status
)) {
569 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
570 if (EFI_ERROR (Status
)) {
578 Platform console init. Include the platform firmware vendor, revision
584 PlatformConsoleInit (
588 gUartDeviceNode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
589 gUartDeviceNode
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
590 gUartDeviceNode
.Parity
= PcdGet8 (PcdUartDefaultParity
);
591 gUartDeviceNode
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
593 ConnectRootBridge ();
596 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
598 DetectAndPreparePlatformPciDevicePaths (FALSE
);