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)
47 #define gPnpPs2Keyboard \
48 PNPID_DEVICE_PATH_NODE(0x0303)
53 HARDWARE_DEVICE_PATH, \
56 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
57 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
60 EDKII_SERIAL_PORT_LIB_VENDOR_GUID \
66 MESSAGING_DEVICE_PATH, \
69 (UINT8) (sizeof (UART_DEVICE_PATH)), \
70 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
80 #define gPcAnsiTerminal \
83 MESSAGING_DEVICE_PATH, \
86 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
87 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
90 DEVICE_PATH_MESSAGING_PC_ANSI \
93 ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode
= gPnpPs2Keyboard
;
94 ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode
= gPnp16550ComPort
;
95 UART_DEVICE_PATH gUartDeviceNode
= gUart
;
96 VENDOR_DEVICE_PATH gTerminalTypeDeviceNode
= gPcAnsiTerminal
;
97 VENDOR_DEVICE_PATH gUartDeviceVendorNode
= gUartVendor
;
100 // Predefined platform root bridge
102 PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0
= {
107 EFI_DEVICE_PATH_PROTOCOL
*gPlatformRootBridges
[] = {
108 (EFI_DEVICE_PATH_PROTOCOL
*)&gPlatformRootBridge0
,
112 BOOLEAN mDetectVgaOnly
;
115 Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
117 @param[in] DeviceHandle Handle of the LPC Bridge device.
119 @retval EFI_SUCCESS Console devices on the LPC bridge have been added to
120 ConOut, ConIn, and ErrOut.
122 @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
126 PrepareLpcBridgeDevicePath (
127 IN EFI_HANDLE DeviceHandle
131 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
132 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
135 Status
= gBS
->HandleProtocol (
137 &gEfiDevicePathProtocolGuid
,
140 if (EFI_ERROR (Status
)) {
144 TempDevicePath
= DevicePath
;
149 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
150 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
155 DevicePath
= TempDevicePath
;
156 DevicePath
= AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*)NULL
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceVendorNode
);
157 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
158 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
160 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
161 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
162 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
168 Return the GOP device path in the platform.
170 @param[in] PciDevicePath - Device path for the PCI graphics device.
171 @param[out] GopDevicePath - Return the device path with GOP installed.
173 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
174 @retval EFI_INVALID_PARAMETER - The device path parameter is invalid.
175 @retval EFI_STATUS - No GOP device found.
179 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
180 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
185 EFI_HANDLE PciDeviceHandle
;
186 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
187 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
188 UINTN GopHandleCount
;
189 EFI_HANDLE
*GopHandleBuffer
;
191 if ((PciDevicePath
== NULL
) || (GopDevicePath
== NULL
)) {
192 return EFI_INVALID_PARAMETER
;
196 // Initialize the GopDevicePath to be PciDevicePath
198 *GopDevicePath
= PciDevicePath
;
199 TempPciDevicePath
= PciDevicePath
;
201 Status
= gBS
->LocateDevicePath (
202 &gEfiDevicePathProtocolGuid
,
206 if (EFI_ERROR (Status
)) {
210 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
212 Status
= gBS
->LocateHandleBuffer (
214 &gEfiGraphicsOutputProtocolGuid
,
219 if (!EFI_ERROR (Status
)) {
221 // Add all the child handles as possible Console Device
223 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
224 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
225 if (EFI_ERROR (Status
)) {
232 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
236 // In current implementation, we only enable one of the child handles
237 // as console device, i.e. sotre one of the child handle's device
238 // path to variable "ConOut"
239 // In future, we could select all child handles to be console device
241 *GopDevicePath
= TempDevicePath
;
244 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
245 // Add the integrity GOP device path.
247 EfiBootManagerUpdateConsoleVariable (ConOut
, NULL
, PciDevicePath
);
248 EfiBootManagerUpdateConsoleVariable (ConOut
, TempDevicePath
, NULL
);
252 gBS
->FreePool (GopHandleBuffer
);
259 Add PCI VGA to ConOut, ConIn, ErrOut.
261 @param[in] DeviceHandle - Handle of PciIo protocol.
263 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
264 @retval EFI_STATUS - No PCI VGA device is added.
268 PreparePciVgaDevicePath (
269 IN EFI_HANDLE DeviceHandle
273 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
274 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
277 Status
= gBS
->HandleProtocol (
279 &gEfiDevicePathProtocolGuid
,
282 if (EFI_ERROR (Status
)) {
286 GetGopDevicePath (DevicePath
, &GopDevicePath
);
287 DevicePath
= GopDevicePath
;
289 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
295 Add PCI Serial to ConOut, ConIn, ErrOut.
297 @param[in] DeviceHandle - Handle of PciIo protocol.
299 @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
300 @retval EFI_STATUS - No PCI Serial device is added.
304 PreparePciSerialDevicePath (
305 IN EFI_HANDLE DeviceHandle
309 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
312 Status
= gBS
->HandleProtocol (
314 &gEfiDevicePathProtocolGuid
,
317 if (EFI_ERROR (Status
)) {
321 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
322 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
324 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
325 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
326 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
332 For every PCI instance execute a callback function.
334 @param[in] Id - The protocol GUID for callback
335 @param[in] CallBackFunction - The callback function
336 @param[in] Context - The context of the callback
338 @retval EFI_STATUS - Callback function failed.
343 VisitAllInstancesOfProtocol (
345 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
351 EFI_HANDLE
*HandleBuffer
;
356 // Start to check all the PciIo to find all possible device
360 Status
= gBS
->LocateHandleBuffer (
367 if (EFI_ERROR (Status
)) {
371 for (Index
= 0; Index
< HandleCount
; Index
++) {
372 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
373 if (EFI_ERROR (Status
)) {
377 Status
= (*CallBackFunction
)(
384 gBS
->FreePool (HandleBuffer
);
390 For every PCI instance execute a callback function.
392 @param[in] Handle - The PCI device handle
393 @param[in] Instance - The instance of the PciIo protocol
394 @param[in] Context - The context of the callback
396 @retval EFI_STATUS - Callback function failed.
401 VisitingAPciInstance (
402 IN EFI_HANDLE Handle
,
408 EFI_PCI_IO_PROTOCOL
*PciIo
;
411 PciIo
= (EFI_PCI_IO_PROTOCOL
*)Instance
;
414 // Check for all PCI device
416 Status
= PciIo
->Pci
.Read (
420 sizeof (Pci
) / sizeof (UINT32
),
423 if (EFI_ERROR (Status
)) {
427 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
)Context
)(
435 For every PCI instance execute a callback function.
437 @param[in] CallBackFunction - Callback function pointer
439 @retval EFI_STATUS - Callback function failed.
444 VisitAllPciInstances (
445 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
448 return VisitAllInstancesOfProtocol (
449 &gEfiPciIoProtocolGuid
,
450 VisitingAPciInstance
,
451 (VOID
*)(UINTN
)CallBackFunction
456 Do platform specific PCI Device check and add them to
457 ConOut, ConIn, ErrOut.
459 @param[in] Handle - Handle of PCI device instance
460 @param[in] PciIo - PCI IO protocol instance
461 @param[in] Pci - PCI Header register block
463 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
464 @retval EFI_STATUS - PCI Device check or Console variable update fail.
469 DetectAndPreparePlatformPciDevicePath (
470 IN EFI_HANDLE Handle
,
471 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
477 Status
= PciIo
->Attributes (
479 EfiPciIoAttributeOperationEnable
,
480 EFI_PCI_DEVICE_ENABLE
,
483 ASSERT_EFI_ERROR (Status
);
485 if (!mDetectVgaOnly
) {
487 // Here we decide whether it is LPC Bridge
489 if ((IS_PCI_LPC (Pci
)) ||
490 ((IS_PCI_ISA_PDECODE (Pci
)) &&
491 (Pci
->Hdr
.VendorId
== 0x8086)
496 // Add IsaKeyboard to ConIn,
497 // add IsaSerial to ConOut, ConIn, ErrOut
499 DEBUG ((DEBUG_INFO
, "Found LPC Bridge device\n"));
500 PrepareLpcBridgeDevicePath (Handle
);
505 // Here we decide which Serial device to enable in PCI bus
507 if (IS_PCI_16550SERIAL (Pci
)) {
509 // Add them to ConOut, ConIn, ErrOut.
511 DEBUG ((DEBUG_INFO
, "Found PCI 16550 SERIAL device\n"));
512 PreparePciSerialDevicePath (Handle
);
518 // Here we decide which VGA device to enable in PCI bus
520 if (IS_PCI_VGA (Pci
)) {
522 // Add them to ConOut.
524 DEBUG ((DEBUG_INFO
, "Found PCI VGA device\n"));
525 PreparePciVgaDevicePath (Handle
);
533 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
535 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
537 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
538 @retval EFI_STATUS - PCI Device check or Console variable update fail.
542 DetectAndPreparePlatformPciDevicePaths (
543 BOOLEAN DetectVgaOnly
546 mDetectVgaOnly
= DetectVgaOnly
;
548 EfiBootManagerUpdateConsoleVariable (
550 (EFI_DEVICE_PATH_PROTOCOL
*)&gUsbClassKeyboardDevicePath
,
554 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
558 The function will connect root bridge
560 @return EFI_SUCCESS Connect RootBridge successfully.
569 EFI_HANDLE RootHandle
;
572 // Make all the PCI_IO protocols on PCI Seg 0 show up
574 Status
= gBS
->LocateDevicePath (
575 &gEfiDevicePathProtocolGuid
,
576 &gPlatformRootBridges
[0],
579 if (EFI_ERROR (Status
)) {
583 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
584 if (EFI_ERROR (Status
)) {
592 Platform console init. Include the platform firmware vendor, revision
598 PlatformConsoleInit (
602 gUartDeviceNode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
603 gUartDeviceNode
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
604 gUartDeviceNode
.Parity
= PcdGet8 (PcdUartDefaultParity
);
605 gUartDeviceNode
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
607 ConnectRootBridge ();
610 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
612 DetectAndPreparePlatformPciDevicePaths (FALSE
);