+/** @file\r
+ Platform BDS customizations.\r
+\r
+ Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "BdsPlatform.h"\r
+\r
+\r
+//\r
+// BDS Platform Functions\r
+//\r
+VOID\r
+EFIAPI\r
+PlatformBdsInit (\r
+ IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Platform Bds init. Incude the platform firmware vendor, revision\r
+ and so crc check.\r
+\r
+Arguments:\r
+\r
+ PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ConnectRootBridge (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Connect RootBridge\r
+\r
+Arguments:\r
+\r
+ None.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Connect RootBridge successfully.\r
+ EFI_STATUS - Connect RootBridge fail.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE RootHandle;\r
+\r
+ //\r
+ // Make all the PCI_IO protocols on PCI Seg 0 show up\r
+ //\r
+ BdsLibConnectDevicePath (gPlatformRootBridges[0]);\r
+\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &gPlatformRootBridges[0],\r
+ &RootHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PrepareLpcBridgeDevicePath (\r
+ IN EFI_HANDLE DeviceHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add IsaKeyboard to ConIn,\r
+ add IsaSerial to ConOut, ConIn, ErrOut.\r
+ LPC Bridge: 06 01 00\r
+\r
+Arguments:\r
+\r
+ DeviceHandle - Handle of PCIIO protocol.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
+ EFI_STATUS - No LPC bridge is added.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ CHAR16 *DevPathStr;\r
+\r
+ DevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ DeviceHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID*)&DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ TempDevicePath = DevicePath;\r
+\r
+ //\r
+ // Register Keyboard\r
+ //\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
+\r
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
+\r
+ //\r
+ // Register COM1\r
+ //\r
+ DevicePath = TempDevicePath;\r
+ gPnp16550ComPortDeviceNode.UID = 0;\r
+\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+\r
+ //\r
+ // Print Device Path\r
+ //\r
+ DevPathStr = DevicePathToStr(DevicePath);\r
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+ __LINE__,\r
+ gPnp16550ComPortDeviceNode.UID + 1,\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\r
+\r
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
+\r
+ //\r
+ // Register COM2\r
+ //\r
+ DevicePath = TempDevicePath;\r
+ gPnp16550ComPortDeviceNode.UID = 1;\r
+\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+\r
+ //\r
+ // Print Device Path\r
+ //\r
+ DevPathStr = DevicePathToStr(DevicePath);\r
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+ __LINE__,\r
+ gPnp16550ComPortDeviceNode.UID + 1,\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\r
+\r
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetGopDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
+ )\r
+{\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE PciDeviceHandle;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
+ UINTN GopHandleCount;\r
+ EFI_HANDLE *GopHandleBuffer;\r
+\r
+ if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Initialize the GopDevicePath to be PciDevicePath\r
+ //\r
+ *GopDevicePath = PciDevicePath;\r
+ TempPciDevicePath = PciDevicePath;\r
+\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &TempPciDevicePath,\r
+ &PciDeviceHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Try to connect this handle, so that GOP dirver could start on this\r
+ // device and create child handles with GraphicsOutput Protocol installed\r
+ // on them, then we get device paths of these child handles and select\r
+ // them as possible console device.\r
+ //\r
+ gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ NULL,\r
+ &GopHandleCount,\r
+ &GopHandleBuffer\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Add all the child handles as possible Console Device\r
+ //\r
+ for (Index = 0; Index < GopHandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ if (CompareMem (\r
+ PciDevicePath,\r
+ TempDevicePath,\r
+ GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
+ ) == 0) {\r
+ //\r
+ // In current implementation, we only enable one of the child handles\r
+ // as console device, i.e. sotre one of the child handle's device\r
+ // path to variable "ConOut"\r
+ // In futhure, we could select all child handles to be console device\r
+ //\r
+\r
+ *GopDevicePath = TempDevicePath;\r
+\r
+ //\r
+ // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
+ // Add the integrity GOP device path.\r
+ //\r
+ BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);\r
+ BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);\r
+ }\r
+ }\r
+ gBS->FreePool (GopHandleBuffer);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PreparePciVgaDevicePath (\r
+ IN EFI_HANDLE DeviceHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add PCI VGA to ConOut.\r
+ PCI VGA: 03 00 00\r
+\r
+Arguments:\r
+\r
+ DeviceHandle - Handle of PCIIO protocol.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - PCI VGA is added to ConOut.\r
+ EFI_STATUS - No PCI VGA device is added.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
+\r
+ DevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ DeviceHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID*)&DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ GetGopDevicePath (DevicePath, &GopDevicePath);\r
+ DevicePath = GopDevicePath;\r
+\r
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PreparePciSerialDevicePath (\r
+ IN EFI_HANDLE DeviceHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add PCI Serial to ConOut, ConIn, ErrOut.\r
+ PCI Serial: 07 00 02\r
+\r
+Arguments:\r
+\r
+ DeviceHandle - Handle of PCIIO protocol.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
+ EFI_STATUS - No PCI Serial device is added.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+ DevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ DeviceHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID*)&DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+\r
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DetectAndPreparePlatformPciDevicePath (\r
+ BOOLEAN DetectVgaOnly\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+\r
+Arguments:\r
+\r
+ DetectVgaOnly - Only detect VGA device if it's TRUE.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+ EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN Index;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ PCI_TYPE00 Pci;\r
+\r
+ //\r
+ // Start to check all the PciIo to find all possible device\r
+ //\r
+ HandleCount = 0;\r
+ HandleBuffer = NULL;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiPciIoProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check for all PCI device\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0,\r
+ sizeof (Pci) / sizeof (UINT32),\r
+ &Pci\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (!DetectVgaOnly) {\r
+ //\r
+ // Here we decide whether it is LPC Bridge\r
+ //\r
+ if ((IS_PCI_LPC (&Pci)) ||\r
+ ((IS_PCI_ISA_PDECODE (&Pci)) &&\r
+ (Pci.Hdr.VendorId == 0x8086) &&\r
+ (Pci.Hdr.DeviceId == 0x7000)\r
+ )\r
+ ) {\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ //\r
+ // Add IsaKeyboard to ConIn,\r
+ // add IsaSerial to ConOut, ConIn, ErrOut\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));\r
+ PrepareLpcBridgeDevicePath (HandleBuffer[Index]);\r
+ continue;\r
+ }\r
+ //\r
+ // Here we decide which Serial device to enable in PCI bus\r
+ //\r
+ if (IS_PCI_16550SERIAL (&Pci)) {\r
+ //\r
+ // Add them to ConOut, ConIn, ErrOut.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));\r
+ PreparePciSerialDevicePath (HandleBuffer[Index]);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if ((Pci.Hdr.VendorId == 0x8086) &&\r
+ (Pci.Hdr.DeviceId == 0x7010)\r
+ ) {\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ //\r
+ // Here we decide which VGA device to enable in PCI bus\r
+ //\r
+ if (IS_PCI_VGA (&Pci)) {\r
+ //\r
+ // Add them to ConOut.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Find the VGA device\n"));\r
+ PreparePciVgaDevicePath (HandleBuffer[Index]);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ gBS->FreePool (HandleBuffer);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PlatformBdsConnectConsole (\r
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Connect the predefined platform default console device. Always try to find\r
+ and enable the vga device if have.\r
+\r
+Arguments:\r
+\r
+ PlatformConsole - Predfined platform default console device array.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Success connect at least one ConIn and ConOut\r
+ device, there must have one ConOut device is\r
+ active vga device.\r
+\r
+ EFI_STATUS - Return the status of\r
+ BdsLibConnectAllDefaultConsoles ()\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
+ EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
+ UINTN DevicePathSize;\r
+\r
+ //\r
+ // Connect RootBridge\r
+ //\r
+ ConnectRootBridge ();\r
+\r
+ VarConout = BdsLibGetVariableAndSize (\r
+ VarConsoleOut,\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+ VarConin = BdsLibGetVariableAndSize (\r
+ VarConsoleInp,\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+\r
+ if (VarConout == NULL || VarConin == NULL) {\r
+ //\r
+ // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+ //\r
+ DetectAndPreparePlatformPciDevicePath (FALSE);\r
+\r
+ //\r
+ // Have chance to connect the platform default console,\r
+ // the platform default console is the minimue device group\r
+ // the platform should support\r
+ //\r
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
+ //\r
+ // Update the console variable with the connect type\r
+ //\r
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
+ BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
+ }\r
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
+ BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
+ }\r
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
+ BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // Only detect VGA device and add them to ConOut\r
+ //\r
+ DetectAndPreparePlatformPciDevicePath (TRUE);\r
+ }\r
+\r
+ //\r
+ // Connect the all the default console with current cosole variable\r
+ //\r
+ Status = BdsLibConnectAllDefaultConsoles ();\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+PciInitialization (\r
+ )\r
+{\r
+ //\r
+ // Device 0 Function 0\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,0,0,0x3c), 0x00);\r
+\r
+ //\r
+ // Device 1 Function 0\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x60), 0x8b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x61), 0x89);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x62), 0x0a);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x63), 0x89);\r
+ //PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x82), 0x02);\r
+\r
+ //\r
+ // Device 1 Function 1\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,1,0x3c), 0x00);\r
+\r
+ //\r
+ // Device 1 Function 3\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3c), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3d), 0x01);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x5f), 0x90);\r
+\r
+ //\r
+ // Device 2 Function 0\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,2,0,0x3c), 0x00);\r
+\r
+ //\r
+ // Device 3 Function 0\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3c), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);\r
+}\r
+\r
+\r
+VOID\r
+PlatformBdsConnectSequence (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Connect with predeined platform connect sequence,\r
+ the OEM/IBV can customize with their own connect sequence.\r
+\r
+Arguments:\r
+\r
+ None.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
+\r
+ Index = 0;\r
+\r
+ //\r
+ // Here we can get the customized platform connect sequence\r
+ // Notes: we can connect with new variable which record the\r
+ // last time boots connect device path sequence\r
+ //\r
+ while (gPlatformConnectSequence[Index] != NULL) {\r
+ //\r
+ // Build the platform boot option\r
+ //\r
+ BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
+ Index++;\r
+ }\r
+\r
+ //\r
+ // Just use the simple policy to connect all devices\r
+ //\r
+ BdsLibConnectAll ();\r
+\r
+ PciInitialization ();\r
+}\r
+\r
+VOID\r
+PlatformBdsGetDriverOption (\r
+ IN OUT LIST_ENTRY *BdsDriverLists\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Load the predefined driver option, OEM/IBV can customize this\r
+ to load their own drivers\r
+\r
+Arguments:\r
+\r
+ BdsDriverLists - The header of the driver option link list.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
+ return;\r
+}\r
+\r
+VOID\r
+PlatformBdsDiagnostics (\r
+ IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
+ IN BOOLEAN QuietBoot\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Perform the platform diagnostic, such like test memory. OEM/IBV also\r
+ can customize this fuction to support specific platform diagnostic.\r
+\r
+Arguments:\r
+\r
+ MemoryTestLevel - The memory test intensive level\r
+\r
+ QuietBoot - Indicate if need to enable the quiet boot\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
+\r
+ //\r
+ // Here we can decide if we need to show\r
+ // the diagnostics screen\r
+ // Notes: this quiet boot code should be remove\r
+ // from the graphic lib\r
+ //\r
+ if (QuietBoot) {\r
+ EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
+ //\r
+ // Perform system diagnostic\r
+ //\r
+ Status = BdsMemoryTest (MemoryTestLevel);\r
+ if (EFI_ERROR (Status)) {\r
+ DisableQuietBoot ();\r
+ }\r
+\r
+ return ;\r
+ }\r
+ //\r
+ // Perform system diagnostic\r
+ //\r
+ Status = BdsMemoryTest (MemoryTestLevel);\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsPolicyBehavior (\r
+ IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData,\r
+ IN OUT LIST_ENTRY *DriverOptionList,\r
+ IN OUT LIST_ENTRY *BootOptionList\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The function will excute with as the platform policy, current policy\r
+ is driven by boot mode. IBV/OEM can customize this code for their specific\r
+ policy action.\r
+\r
+Arguments:\r
+\r
+ PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
+\r
+ DriverOptionList - The header of the driver option link list\r
+\r
+ BootOptionList - The header of the boot option link list\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT16 Timeout;\r
+ EFI_EVENT UserInputDurationTime;\r
+ LIST_ENTRY *Link;\r
+ BDS_COMMON_OPTION *BootOption;\r
+ UINTN Index;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_TPL OldTpl;\r
+\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
+\r
+ //\r
+ // Init the time out value\r
+ //\r
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+\r
+ //\r
+ // Load the driver option as the driver option list\r
+ //\r
+ PlatformBdsGetDriverOption (DriverOptionList);\r
+\r
+ //\r
+ // Get current Boot Mode\r
+ //\r
+ Status = BdsLibGetBootMode (&PrivateData->BootMode);\r
+ DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", PrivateData->BootMode));\r
+\r
+ //\r
+ // Go the different platform policy with different boot mode\r
+ // Notes: this part code can be change with the table policy\r
+ //\r
+ ASSERT (PrivateData->BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
+ //\r
+ // Connect platform console\r
+ //\r
+ Status = PlatformBdsConnectConsole (gPlatformConsole);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Here OEM/IBV can customize with defined action\r
+ //\r
+ PlatformBdsNoConsoleAction ();\r
+ }\r
+ //\r
+ // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ 0,\r
+ NULL,\r
+ NULL,\r
+ &UserInputDurationTime\r
+ );\r
+ ASSERT (Status == EFI_SUCCESS);\r
+ Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
+ ASSERT (Status == EFI_SUCCESS);\r
+ //\r
+ // Memory test and Logo show\r
+ //\r
+ PlatformBdsDiagnostics (IGNORE, TRUE);\r
+\r
+ //\r
+ // Perform some platform specific connect sequence\r
+ //\r
+ PlatformBdsConnectSequence ();\r
+\r
+ //\r
+ // Give one chance to enter the setup if we\r
+ // have the time out\r
+ //\r
+ if (Timeout != 0) {\r
+ //PlatformBdsEnterFrontPage (Timeout, FALSE);\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
+ BdsLibConnectAll ();\r
+ BdsLibEnumerateAllBootOption (BootOptionList);\r
+\r
+ //\r
+ // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
+ // checking code in real production tip.\r
+ //\r
+ // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
+ // and do enumerate all the default boot options. But in development system board, the boot mode\r
+ // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
+ // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
+ //\r
+ Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
+ if (EFI_ERROR(Status)) {\r
+ //\r
+ // If cannot find "BootOrder" variable, it may be first boot.\r
+ // Try to connect all devices and enumerate all boot options here.\r
+ //\r
+ BdsLibConnectAll ();\r
+ BdsLibEnumerateAllBootOption (BootOptionList);\r
+ }\r
+\r
+ //\r
+ // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
+ // BDS should still give user a chance to enter Setup\r
+ //\r
+ // Connect first boot option, and then check user input before exit\r
+ //\r
+ for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
+ BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
+ if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
+ //\r
+ // skip the header of the link list, becuase it has no boot option\r
+ //\r
+ continue;\r
+ } else {\r
+ //\r
+ // Make sure the boot option device path connected, but ignore the BBS device path\r
+ //\r
+ if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
+ BdsLibConnectDevicePath (BootOption->DevicePath);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check whether the user input after the duration time has expired\r
+ //\r
+ OldTpl = EfiGetCurrentTpl();\r
+ gBS->RestoreTPL (TPL_APPLICATION);\r
+ gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
+ gBS->CloseEvent (UserInputDurationTime);\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ gBS->RaiseTPL (OldTpl);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Enter Setup if user input\r
+ //\r
+ Timeout = 0xffff;\r
+ PlatformBdsEnterFrontPage (Timeout, FALSE);\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsBootSuccess (\r
+ IN BDS_COMMON_OPTION *Option\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Hook point after a boot attempt succeeds. We don't expect a boot option to\r
+ return, so the EFI 1.0 specification defines that you will default to an\r
+ interactive mode and stop processing the BootOrder list in this case. This\r
+ is alos a platform implementation and can be customized by IBV/OEM.\r
+\r
+Arguments:\r
+\r
+ Option - Pointer to Boot Option that succeeded to boot.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ CHAR16 *TmpStr;\r
+\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
+ //\r
+ // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
+ // select loop then we need to pop up a UI and wait for user input.\r
+ //\r
+ TmpStr = Option->StatusString;\r
+ if (TmpStr != NULL) {\r
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
+ FreePool (TmpStr);\r
+ }\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsBootFail (\r
+ IN BDS_COMMON_OPTION *Option,\r
+ IN EFI_STATUS Status,\r
+ IN CHAR16 *ExitData,\r
+ IN UINTN ExitDataSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Hook point after a boot attempt fails.\r
+\r
+Arguments:\r
+\r
+ Option - Pointer to Boot Option that failed to boot.\r
+\r
+ Status - Status returned from failed boot.\r
+\r
+ ExitData - Exit data returned from failed boot.\r
+\r
+ ExitDataSize - Exit data size returned from failed boot.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ CHAR16 *TmpStr;\r
+\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
+\r
+ //\r
+ // If Boot returned with failed status then we need to pop up a UI and wait\r
+ // for user input.\r
+ //\r
+ TmpStr = Option->StatusString;\r
+ if (TmpStr != NULL) {\r
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
+ FreePool (TmpStr);\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+PlatformBdsNoConsoleAction (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function is remained for IBV/OEM to do some platform action,\r
+ if there no console device can be connected.\r
+\r
+Arguments:\r
+\r
+ None.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Direct return success now.\r
+\r
+--*/\r
+{\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformBdsLockNonUpdatableFlash (\r
+ VOID\r
+ )\r
+{\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
+ return EFI_SUCCESS;\r
+}\r