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"
12 #define PCI_DEVICE_PATH_NODE(Func, Dev) \
15 HARDWARE_DEVICE_PATH, \
18 (UINT8) (sizeof (PCI_DEVICE_PATH)), \
19 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
26 #define PNPID_DEVICE_PATH_NODE(PnpId) \
32 (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
33 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
36 EISA_PNP_ID((PnpId)), \
40 #define gPciRootBridge \
41 PNPID_DEVICE_PATH_NODE(0x0A03)
43 #define gPnp16550ComPort \
44 PNPID_DEVICE_PATH_NODE(0x0501)
49 HARDWARE_DEVICE_PATH, \
52 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
53 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
56 {0xD3987D4B, 0x971A, 0x435F, {0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41}} \
62 MESSAGING_DEVICE_PATH, \
65 (UINT8) (sizeof (UART_DEVICE_PATH)), \
66 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
76 #define gPcAnsiTerminal \
79 MESSAGING_DEVICE_PATH, \
82 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
83 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
86 DEVICE_PATH_MESSAGING_PC_ANSI \
90 ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode
= gPnp16550ComPort
;
91 UART_DEVICE_PATH gUartDeviceNode
= gUart
;
92 VENDOR_DEVICE_PATH gTerminalTypeDeviceNode
= gPcAnsiTerminal
;
93 VENDOR_DEVICE_PATH gUartDeviceVendorNode
= gUartVendor
;
96 // Predefined platform root bridge
98 PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0
= {
103 EFI_DEVICE_PATH_PROTOCOL
*gPlatformRootBridges
[] = {
104 (EFI_DEVICE_PATH_PROTOCOL
*) &gPlatformRootBridge0
,
108 BOOLEAN mDetectVgaOnly
;
111 Add UART to ConOut, ConIn, ErrOut.
113 @param[in] DeviceHandle - LPC device path.
115 @retval EFI_SUCCESS - Serial console is added to ConOut, ConIn, and ErrOut.
116 @retval EFI_STATUS - No serial console is added.
119 PrepareLpcBridgeDevicePath (
120 IN EFI_HANDLE DeviceHandle
124 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
127 Status
= gBS
->HandleProtocol (
129 &gEfiDevicePathProtocolGuid
,
132 if (EFI_ERROR (Status
)) {
139 DevicePath
= AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*)NULL
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceVendorNode
);
140 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
141 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
143 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
144 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
145 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
151 Return the GOP device path in the platform.
153 @param[in] PciDevicePath - Device path for the PCI graphics device.
154 @param[out] GopDevicePath - Return the device path with GOP installed.
156 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
157 @retval EFI_INVALID_PARAMETER - The device path parameter is invalid.
158 @retval EFI_STATUS - No GOP device found.
162 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
163 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
168 EFI_HANDLE PciDeviceHandle
;
169 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
170 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
171 UINTN GopHandleCount
;
172 EFI_HANDLE
*GopHandleBuffer
;
174 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
175 return EFI_INVALID_PARAMETER
;
179 // Initialize the GopDevicePath to be PciDevicePath
181 *GopDevicePath
= PciDevicePath
;
182 TempPciDevicePath
= PciDevicePath
;
184 Status
= gBS
->LocateDevicePath (
185 &gEfiDevicePathProtocolGuid
,
189 if (EFI_ERROR (Status
)) {
193 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
195 Status
= gBS
->LocateHandleBuffer (
197 &gEfiGraphicsOutputProtocolGuid
,
202 if (!EFI_ERROR (Status
)) {
204 // Add all the child handles as possible Console Device
206 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
207 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
208 if (EFI_ERROR (Status
)) {
214 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
217 // In current implementation, we only enable one of the child handles
218 // as console device, i.e. sotre one of the child handle's device
219 // path to variable "ConOut"
220 // In future, we could select all child handles to be console device
222 *GopDevicePath
= TempDevicePath
;
225 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
226 // Add the integrity GOP device path.
228 EfiBootManagerUpdateConsoleVariable (ConOut
, NULL
, PciDevicePath
);
229 EfiBootManagerUpdateConsoleVariable (ConOut
, TempDevicePath
, NULL
);
232 gBS
->FreePool (GopHandleBuffer
);
239 Add PCI VGA to ConOut, ConIn, ErrOut.
241 @param[in] DeviceHandle - Handle of PciIo protocol.
243 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
244 @retval EFI_STATUS - No PCI VGA device is added.
248 PreparePciVgaDevicePath (
249 IN EFI_HANDLE DeviceHandle
253 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
254 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
257 Status
= gBS
->HandleProtocol (
259 &gEfiDevicePathProtocolGuid
,
262 if (EFI_ERROR (Status
)) {
266 GetGopDevicePath (DevicePath
, &GopDevicePath
);
267 DevicePath
= GopDevicePath
;
269 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
275 Add PCI Serial to ConOut, ConIn, ErrOut.
277 @param[in] DeviceHandle - Handle of PciIo protocol.
279 @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
280 @retval EFI_STATUS - No PCI Serial device is added.
284 PreparePciSerialDevicePath (
285 IN EFI_HANDLE DeviceHandle
289 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
292 Status
= gBS
->HandleProtocol (
294 &gEfiDevicePathProtocolGuid
,
297 if (EFI_ERROR (Status
)) {
301 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
302 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
304 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
305 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
306 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
313 For every PCI instance execute a callback function.
315 @param[in] Id - The protocol GUID for callback
316 @param[in] CallBackFunction - The callback function
317 @param[in] Context - The context of the callback
319 @retval EFI_STATUS - Callback function failed.
324 VisitAllInstancesOfProtocol (
326 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
332 EFI_HANDLE
*HandleBuffer
;
337 // Start to check all the PciIo to find all possible device
341 Status
= gBS
->LocateHandleBuffer (
348 if (EFI_ERROR (Status
)) {
352 for (Index
= 0; Index
< HandleCount
; Index
++) {
353 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
354 if (EFI_ERROR (Status
)) {
358 Status
= (*CallBackFunction
) (
365 gBS
->FreePool (HandleBuffer
);
372 For every PCI instance execute a callback function.
374 @param[in] Handle - The PCI device handle
375 @param[in] Instance - The instance of the PciIo protocol
376 @param[in] Context - The context of the callback
378 @retval EFI_STATUS - Callback function failed.
383 VisitingAPciInstance (
384 IN EFI_HANDLE Handle
,
390 EFI_PCI_IO_PROTOCOL
*PciIo
;
393 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
396 // Check for all PCI device
398 Status
= PciIo
->Pci
.Read (
402 sizeof (Pci
) / sizeof (UINT32
),
405 if (EFI_ERROR (Status
)) {
409 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
419 For every PCI instance execute a callback function.
421 @param[in] CallBackFunction - Callback function pointer
423 @retval EFI_STATUS - Callback function failed.
428 VisitAllPciInstances (
429 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
432 return VisitAllInstancesOfProtocol (
433 &gEfiPciIoProtocolGuid
,
434 VisitingAPciInstance
,
435 (VOID
*)(UINTN
) CallBackFunction
441 Do platform specific PCI Device check and add them to
442 ConOut, ConIn, ErrOut.
444 @param[in] Handle - Handle of PCI device instance
445 @param[in] PciIo - PCI IO protocol instance
446 @param[in] Pci - PCI Header register block
448 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
449 @retval EFI_STATUS - PCI Device check or Console variable update fail.
454 DetectAndPreparePlatformPciDevicePath (
455 IN EFI_HANDLE Handle
,
456 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
462 Status
= PciIo
->Attributes (
464 EfiPciIoAttributeOperationEnable
,
465 EFI_PCI_DEVICE_ENABLE
,
468 ASSERT_EFI_ERROR (Status
);
470 if (!mDetectVgaOnly
) {
472 // Here we decide whether it is LPC Bridge
474 if ((IS_PCI_LPC (Pci
)) ||
475 ((IS_PCI_ISA_PDECODE (Pci
)) &&
476 (Pci
->Hdr
.VendorId
== 0x8086)
480 // Add IsaKeyboard to ConIn,
481 // add IsaSerial to ConOut, ConIn, ErrOut
483 DEBUG ((DEBUG_INFO
, "Found LPC Bridge device\n"));
484 PrepareLpcBridgeDevicePath (Handle
);
488 // Here we decide which Serial device to enable in PCI bus
490 if (IS_PCI_16550SERIAL (Pci
)) {
492 // Add them to ConOut, ConIn, ErrOut.
494 DEBUG ((DEBUG_INFO
, "Found PCI 16550 SERIAL device\n"));
495 PreparePciSerialDevicePath (Handle
);
501 // Here we decide which VGA device to enable in PCI bus
503 if (IS_PCI_VGA (Pci
)) {
505 // Add them to ConOut.
507 DEBUG ((DEBUG_INFO
, "Found PCI VGA device\n"));
508 PreparePciVgaDevicePath (Handle
);
517 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
519 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
521 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
522 @retval EFI_STATUS - PCI Device check or Console variable update fail.
526 DetectAndPreparePlatformPciDevicePaths (
527 BOOLEAN DetectVgaOnly
530 mDetectVgaOnly
= DetectVgaOnly
;
532 EfiBootManagerUpdateConsoleVariable (
534 (EFI_DEVICE_PATH_PROTOCOL
*) &gUsbClassKeyboardDevicePath
,
538 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
543 The function will connect root bridge
545 @return EFI_SUCCESS Connect RootBridge successfully.
554 EFI_HANDLE RootHandle
;
557 // Make all the PCI_IO protocols on PCI Seg 0 show up
559 Status
= gBS
->LocateDevicePath (
560 &gEfiDevicePathProtocolGuid
,
561 &gPlatformRootBridges
[0],
564 if (EFI_ERROR (Status
)) {
568 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
569 if (EFI_ERROR (Status
)) {
577 Platform console init. Include the platform firmware vendor, revision
583 PlatformConsoleInit (
587 gUartDeviceNode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
588 gUartDeviceNode
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
589 gUartDeviceNode
.Parity
= PcdGet8 (PcdUartDefaultParity
);
590 gUartDeviceNode
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
592 ConnectRootBridge ();
595 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
597 DetectAndPreparePlatformPciDevicePaths (FALSE
);