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
;
173 ACPI_ADR_DEVICE_PATH AcpiAdr
;
174 EFI_DEVICE_PATH_PROTOCOL
*MyDevicePath
;
176 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
177 return EFI_INVALID_PARAMETER
;
183 // Initialize the GopDevicePath to be PciDevicePath
185 *GopDevicePath
= PciDevicePath
;
186 TempPciDevicePath
= PciDevicePath
;
188 Status
= gBS
->LocateDevicePath (
189 &gEfiDevicePathProtocolGuid
,
193 if (EFI_ERROR (Status
)) {
198 // Try to connect this handle, so that GOP driver could start on this
199 // device and create child handles with GraphicsOutput Protocol installed
200 // on them, then we get device paths of these child handles and select
201 // them as possible console device.
203 AcpiAdr
.Header
.Type
= ACPI_DEVICE_PATH
;
204 AcpiAdr
.Header
.SubType
= ACPI_ADR_DP
;
205 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, 8, 0);
207 SetDevicePathNodeLength (&AcpiAdr
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
209 MyDevicePath
= AppendDevicePathNode(MyDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&AcpiAdr
);
211 gBS
->ConnectController (PciDeviceHandle
, NULL
, MyDevicePath
, FALSE
);
213 FreePool(MyDevicePath
);
215 Status
= gBS
->LocateHandleBuffer (
217 &gEfiGraphicsOutputProtocolGuid
,
222 if (!EFI_ERROR (Status
)) {
224 // Add all the child handles as possible Console Device
226 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
227 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
228 if (EFI_ERROR (Status
)) {
234 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
237 // In current implementation, we only enable one of the child handles
238 // as console device, i.e. sotre one of the child handle's device
239 // path to variable "ConOut"
240 // In future, we could select all child handles to be console device
242 *GopDevicePath
= TempDevicePath
;
245 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
246 // Add the integrity GOP device path.
248 EfiBootManagerUpdateConsoleVariable (ConOut
, NULL
, PciDevicePath
);
249 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
);
333 For every PCI instance execute a callback function.
335 @param[in] Id - The protocol GUID for callback
336 @param[in] CallBackFunction - The callback function
337 @param[in] Context - The context of the callback
339 @retval EFI_STATUS - Callback function failed.
344 VisitAllInstancesOfProtocol (
346 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
352 EFI_HANDLE
*HandleBuffer
;
357 // Start to check all the PciIo to find all possible device
361 Status
= gBS
->LocateHandleBuffer (
368 if (EFI_ERROR (Status
)) {
372 for (Index
= 0; Index
< HandleCount
; Index
++) {
373 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
374 if (EFI_ERROR (Status
)) {
378 Status
= (*CallBackFunction
) (
385 gBS
->FreePool (HandleBuffer
);
392 For every PCI instance execute a callback function.
394 @param[in] Handle - The PCI device handle
395 @param[in] Instance - The instance of the PciIo protocol
396 @param[in] Context - The context of the callback
398 @retval EFI_STATUS - Callback function failed.
403 VisitingAPciInstance (
404 IN EFI_HANDLE Handle
,
410 EFI_PCI_IO_PROTOCOL
*PciIo
;
413 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
416 // Check for all PCI device
418 Status
= PciIo
->Pci
.Read (
422 sizeof (Pci
) / sizeof (UINT32
),
425 if (EFI_ERROR (Status
)) {
429 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
439 For every PCI instance execute a callback function.
441 @param[in] CallBackFunction - Callback function pointer
443 @retval EFI_STATUS - Callback function failed.
448 VisitAllPciInstances (
449 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
452 return VisitAllInstancesOfProtocol (
453 &gEfiPciIoProtocolGuid
,
454 VisitingAPciInstance
,
455 (VOID
*)(UINTN
) CallBackFunction
461 Do platform specific PCI Device check and add them to
462 ConOut, ConIn, ErrOut.
464 @param[in] Handle - Handle of PCI device instance
465 @param[in] PciIo - PCI IO protocol instance
466 @param[in] Pci - PCI Header register block
468 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
469 @retval EFI_STATUS - PCI Device check or Console variable update fail.
474 DetectAndPreparePlatformPciDevicePath (
475 IN EFI_HANDLE Handle
,
476 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
482 Status
= PciIo
->Attributes (
484 EfiPciIoAttributeOperationEnable
,
485 EFI_PCI_DEVICE_ENABLE
,
488 ASSERT_EFI_ERROR (Status
);
490 if (!mDetectVgaOnly
) {
492 // Here we decide whether it is LPC Bridge
494 if ((IS_PCI_LPC (Pci
)) ||
495 ((IS_PCI_ISA_PDECODE (Pci
)) &&
496 (Pci
->Hdr
.VendorId
== 0x8086)
500 // Add IsaKeyboard to ConIn,
501 // add IsaSerial to ConOut, ConIn, ErrOut
503 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
504 PrepareLpcBridgeDevicePath (Handle
);
508 // Here we decide which Serial device to enable in PCI bus
510 if (IS_PCI_16550SERIAL (Pci
)) {
512 // Add them to ConOut, ConIn, ErrOut.
514 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
515 PreparePciSerialDevicePath (Handle
);
521 // Here we decide which VGA device to enable in PCI bus
523 if (IS_PCI_VGA (Pci
)) {
525 // Add them to ConOut.
527 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
528 PreparePciVgaDevicePath (Handle
);
537 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
539 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
541 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
542 @retval EFI_STATUS - PCI Device check or Console variable update fail.
546 DetectAndPreparePlatformPciDevicePaths (
547 BOOLEAN DetectVgaOnly
550 mDetectVgaOnly
= DetectVgaOnly
;
551 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
556 The function will connect root bridge
558 @return EFI_SUCCESS Connect RootBridge successfully.
567 EFI_HANDLE RootHandle
;
570 // Make all the PCI_IO protocols on PCI Seg 0 show up
572 Status
= gBS
->LocateDevicePath (
573 &gEfiDevicePathProtocolGuid
,
574 &gPlatformRootBridges
[0],
577 if (EFI_ERROR (Status
)) {
581 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
582 if (EFI_ERROR (Status
)) {
590 Platform console init. Include the platform firmware vendor, revision
596 PlatformConsoleInit (
600 gUartDeviceNode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
601 gUartDeviceNode
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
602 gUartDeviceNode
.Parity
= PcdGet8 (PcdUartDefaultParity
);
603 gUartDeviceNode
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
605 ConnectRootBridge ();
608 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
610 DetectAndPreparePlatformPciDevicePaths (FALSE
);