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 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "PlatformBootManager.h"
16 #include "PlatformConsole.h"
18 #define PCI_DEVICE_PATH_NODE(Func, Dev) \
21 HARDWARE_DEVICE_PATH, \
24 (UINT8) (sizeof (PCI_DEVICE_PATH)), \
25 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
32 #define PNPID_DEVICE_PATH_NODE(PnpId) \
38 (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
39 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
42 EISA_PNP_ID((PnpId)), \
46 #define gPciRootBridge \
47 PNPID_DEVICE_PATH_NODE(0x0A03)
49 #define gPnp16550ComPort \
50 PNPID_DEVICE_PATH_NODE(0x0501)
55 HARDWARE_DEVICE_PATH, \
58 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
59 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
62 {0xD3987D4B, 0x971A, 0x435F, {0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41}} \
68 MESSAGING_DEVICE_PATH, \
71 (UINT8) (sizeof (UART_DEVICE_PATH)), \
72 (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
82 #define gPcAnsiTerminal \
85 MESSAGING_DEVICE_PATH, \
88 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
89 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
92 DEVICE_PATH_MESSAGING_PC_ANSI \
96 ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode
= gPnp16550ComPort
;
97 UART_DEVICE_PATH gUartDeviceNode
= gUart
;
98 VENDOR_DEVICE_PATH gTerminalTypeDeviceNode
= gPcAnsiTerminal
;
99 VENDOR_DEVICE_PATH gUartDeviceVendorNode
= gUartVendor
;
102 // Predefined platform root bridge
104 PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0
= {
109 EFI_DEVICE_PATH_PROTOCOL
*gPlatformRootBridges
[] = {
110 (EFI_DEVICE_PATH_PROTOCOL
*) &gPlatformRootBridge0
,
114 BOOLEAN mDetectVgaOnly
;
117 Add UART to ConOut, ConIn, ErrOut.
119 @param[in] DeviceHandle - LPC device path.
121 @retval EFI_SUCCESS - Serial console is added to ConOut, ConIn, and ErrOut.
122 @retval EFI_STATUS - No serial console is added.
125 PrepareLpcBridgeDevicePath (
126 IN EFI_HANDLE DeviceHandle
130 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
133 Status
= gBS
->HandleProtocol (
135 &gEfiDevicePathProtocolGuid
,
138 if (EFI_ERROR (Status
)) {
145 DevicePath
= AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
*)NULL
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceVendorNode
);
146 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
147 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
149 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
150 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
151 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
157 Return the GOP device path in the platform.
159 @param[in] PciDevicePath - Device path for the PCI graphics device.
160 @param[out] GopDevicePath - Return the device path with GOP installed.
162 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
163 @retval EFI_INVALID_PARAMETER - The device path parameter is invalid.
164 @retval EFI_STATUS - No GOP device found.
168 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
169 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
174 EFI_HANDLE PciDeviceHandle
;
175 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
176 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
177 UINTN GopHandleCount
;
178 EFI_HANDLE
*GopHandleBuffer
;
179 ACPI_ADR_DEVICE_PATH AcpiAdr
;
180 EFI_DEVICE_PATH_PROTOCOL
*MyDevicePath
;
182 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
183 return EFI_INVALID_PARAMETER
;
189 // Initialize the GopDevicePath to be PciDevicePath
191 *GopDevicePath
= PciDevicePath
;
192 TempPciDevicePath
= PciDevicePath
;
194 Status
= gBS
->LocateDevicePath (
195 &gEfiDevicePathProtocolGuid
,
199 if (EFI_ERROR (Status
)) {
204 // Try to connect this handle, so that GOP driver could start on this
205 // device and create child handles with GraphicsOutput Protocol installed
206 // on them, then we get device paths of these child handles and select
207 // them as possible console device.
209 AcpiAdr
.Header
.Type
= ACPI_DEVICE_PATH
;
210 AcpiAdr
.Header
.SubType
= ACPI_ADR_DP
;
211 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, 8, 0);
213 SetDevicePathNodeLength (&AcpiAdr
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
215 MyDevicePath
= AppendDevicePathNode(MyDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&AcpiAdr
);
217 gBS
->ConnectController (PciDeviceHandle
, NULL
, MyDevicePath
, FALSE
);
219 FreePool(MyDevicePath
);
221 Status
= gBS
->LocateHandleBuffer (
223 &gEfiGraphicsOutputProtocolGuid
,
228 if (!EFI_ERROR (Status
)) {
230 // Add all the child handles as possible Console Device
232 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
233 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
234 if (EFI_ERROR (Status
)) {
240 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
243 // In current implementation, we only enable one of the child handles
244 // as console device, i.e. sotre one of the child handle's device
245 // path to variable "ConOut"
246 // In future, we could select all child handles to be console device
248 *GopDevicePath
= TempDevicePath
;
251 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
252 // Add the integrity GOP device path.
254 EfiBootManagerUpdateConsoleVariable (ConOut
, NULL
, PciDevicePath
);
255 EfiBootManagerUpdateConsoleVariable (ConOut
, TempDevicePath
, NULL
);
258 gBS
->FreePool (GopHandleBuffer
);
265 Add PCI VGA to ConOut, ConIn, ErrOut.
267 @param[in] DeviceHandle - Handle of PciIo protocol.
269 @retval EFI_SUCCESS - PCI VGA is added to ConOut.
270 @retval EFI_STATUS - No PCI VGA device is added.
274 PreparePciVgaDevicePath (
275 IN EFI_HANDLE DeviceHandle
279 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
280 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
283 Status
= gBS
->HandleProtocol (
285 &gEfiDevicePathProtocolGuid
,
288 if (EFI_ERROR (Status
)) {
292 GetGopDevicePath (DevicePath
, &GopDevicePath
);
293 DevicePath
= GopDevicePath
;
295 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
301 Add PCI Serial to ConOut, ConIn, ErrOut.
303 @param[in] DeviceHandle - Handle of PciIo protocol.
305 @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
306 @retval EFI_STATUS - No PCI Serial device is added.
310 PreparePciSerialDevicePath (
311 IN EFI_HANDLE DeviceHandle
315 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
318 Status
= gBS
->HandleProtocol (
320 &gEfiDevicePathProtocolGuid
,
323 if (EFI_ERROR (Status
)) {
327 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
328 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
330 EfiBootManagerUpdateConsoleVariable (ConOut
, DevicePath
, NULL
);
331 EfiBootManagerUpdateConsoleVariable (ConIn
, DevicePath
, NULL
);
332 EfiBootManagerUpdateConsoleVariable (ErrOut
, DevicePath
, NULL
);
339 For every PCI instance execute a callback function.
341 @param[in] Id - The protocol GUID for callback
342 @param[in] CallBackFunction - The callback function
343 @param[in] Context - The context of the callback
345 @retval EFI_STATUS - Callback function failed.
350 VisitAllInstancesOfProtocol (
352 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
358 EFI_HANDLE
*HandleBuffer
;
363 // Start to check all the PciIo to find all possible device
367 Status
= gBS
->LocateHandleBuffer (
374 if (EFI_ERROR (Status
)) {
378 for (Index
= 0; Index
< HandleCount
; Index
++) {
379 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
380 if (EFI_ERROR (Status
)) {
384 Status
= (*CallBackFunction
) (
391 gBS
->FreePool (HandleBuffer
);
398 For every PCI instance execute a callback function.
400 @param[in] Handle - The PCI device handle
401 @param[in] Instance - The instance of the PciIo protocol
402 @param[in] Context - The context of the callback
404 @retval EFI_STATUS - Callback function failed.
409 VisitingAPciInstance (
410 IN EFI_HANDLE Handle
,
416 EFI_PCI_IO_PROTOCOL
*PciIo
;
419 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
422 // Check for all PCI device
424 Status
= PciIo
->Pci
.Read (
428 sizeof (Pci
) / sizeof (UINT32
),
431 if (EFI_ERROR (Status
)) {
435 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
445 For every PCI instance execute a callback function.
447 @param[in] CallBackFunction - Callback function pointer
449 @retval EFI_STATUS - Callback function failed.
454 VisitAllPciInstances (
455 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
458 return VisitAllInstancesOfProtocol (
459 &gEfiPciIoProtocolGuid
,
460 VisitingAPciInstance
,
461 (VOID
*)(UINTN
) CallBackFunction
467 Do platform specific PCI Device check and add them to
468 ConOut, ConIn, ErrOut.
470 @param[in] Handle - Handle of PCI device instance
471 @param[in] PciIo - PCI IO protocol instance
472 @param[in] Pci - PCI Header register block
474 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
475 @retval EFI_STATUS - PCI Device check or Console variable update fail.
480 DetectAndPreparePlatformPciDevicePath (
481 IN EFI_HANDLE Handle
,
482 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
488 Status
= PciIo
->Attributes (
490 EfiPciIoAttributeOperationEnable
,
491 EFI_PCI_DEVICE_ENABLE
,
494 ASSERT_EFI_ERROR (Status
);
496 if (!mDetectVgaOnly
) {
498 // Here we decide whether it is LPC Bridge
500 if ((IS_PCI_LPC (Pci
)) ||
501 ((IS_PCI_ISA_PDECODE (Pci
)) &&
502 (Pci
->Hdr
.VendorId
== 0x8086)
506 // Add IsaKeyboard to ConIn,
507 // add IsaSerial to ConOut, ConIn, ErrOut
509 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
510 PrepareLpcBridgeDevicePath (Handle
);
514 // Here we decide which Serial device to enable in PCI bus
516 if (IS_PCI_16550SERIAL (Pci
)) {
518 // Add them to ConOut, ConIn, ErrOut.
520 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
521 PreparePciSerialDevicePath (Handle
);
527 // Here we decide which VGA device to enable in PCI bus
529 if (IS_PCI_VGA (Pci
)) {
531 // Add them to ConOut.
533 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
534 PreparePciVgaDevicePath (Handle
);
543 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
545 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
547 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
548 @retval EFI_STATUS - PCI Device check or Console variable update fail.
552 DetectAndPreparePlatformPciDevicePaths (
553 BOOLEAN DetectVgaOnly
556 mDetectVgaOnly
= DetectVgaOnly
;
557 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
562 The function will connect root bridge
564 @return EFI_SUCCESS Connect RootBridge successfully.
573 EFI_HANDLE RootHandle
;
576 // Make all the PCI_IO protocols on PCI Seg 0 show up
578 Status
= gBS
->LocateDevicePath (
579 &gEfiDevicePathProtocolGuid
,
580 &gPlatformRootBridges
[0],
583 if (EFI_ERROR (Status
)) {
587 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
588 if (EFI_ERROR (Status
)) {
596 Platform console init. Include the platform firmware vendor, revision
602 PlatformConsoleInit (
606 gUartDeviceNode
.BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
607 gUartDeviceNode
.DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
608 gUartDeviceNode
.Parity
= PcdGet8 (PcdUartDefaultParity
);
609 gUartDeviceNode
.StopBits
= PcdGet8 (PcdUartDefaultStopBits
);
611 ConnectRootBridge ();
614 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
616 DetectAndPreparePlatformPciDevicePaths (FALSE
);