| /** @file | |
| Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR> | |
| Copyright (c) 2014, ARM Ltd. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "IntelBdsPlatform.h" | |
| /// | |
| /// Predefined platform default time out value | |
| /// | |
| UINT16 gPlatformBootTimeOutDefault; | |
| EFI_STATUS | |
| EFIAPI | |
| PlatformIntelBdsConstructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| gPlatformBootTimeOutDefault = (UINT16)PcdGet16 (PcdPlatformBootTimeOut); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| An empty function to pass error checking of CreateEventEx (). | |
| @param Event Event whose notification function is being invoked. | |
| @param Context Pointer to the notification function's context, | |
| which is implementation-dependent. | |
| **/ | |
| STATIC | |
| VOID | |
| EFIAPI | |
| EmptyCallbackFunction ( | |
| IN EFI_EVENT Event, | |
| IN VOID *Context | |
| ) | |
| { | |
| } | |
| // | |
| // BDS Platform Functions | |
| // | |
| /** | |
| Platform Bds init. Include the platform firmware vendor, revision | |
| and so crc check. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformBdsInit ( | |
| VOID | |
| ) | |
| { | |
| EFI_EVENT EndOfDxeEvent; | |
| EFI_STATUS Status; | |
| // | |
| // Signal EndOfDxe PI Event | |
| // | |
| Status = gBS->CreateEventEx ( | |
| EVT_NOTIFY_SIGNAL, | |
| TPL_CALLBACK, | |
| EmptyCallbackFunction, | |
| NULL, | |
| &gEfiEndOfDxeEventGroupGuid, | |
| &EndOfDxeEvent | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| gBS->SignalEvent (EndOfDxeEvent); | |
| gBS->CloseEvent (EndOfDxeEvent); | |
| } | |
| } | |
| STATIC | |
| EFI_STATUS | |
| GetConsoleDevicePathFromVariable ( | |
| IN CHAR16* ConsoleVarName, | |
| IN CHAR16* DefaultConsolePaths, | |
| OUT EFI_DEVICE_PATH** DevicePaths | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN Size; | |
| EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances; | |
| EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance; | |
| CHAR16* DevicePathStr; | |
| CHAR16* NextDevicePathStr; | |
| EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; | |
| Status = EFI_SUCCESS; | |
| Size = 0; | |
| DevicePathInstances = BdsLibGetVariableAndSize (ConsoleVarName, &gEfiGlobalVariableGuid, &Size); | |
| if (DevicePathInstances == NULL) { | |
| // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial) | |
| if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) { | |
| *DevicePaths = NULL; | |
| return EFI_SUCCESS; | |
| } | |
| Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); | |
| ASSERT_EFI_ERROR(Status); | |
| // Extract the Device Path instances from the multi-device path string | |
| while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) { | |
| NextDevicePathStr = StrStr (DefaultConsolePaths, L";"); | |
| if (NextDevicePathStr == NULL) { | |
| DevicePathStr = DefaultConsolePaths; | |
| DefaultConsolePaths = NULL; | |
| } else { | |
| DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof(CHAR16), DefaultConsolePaths); | |
| *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0'; | |
| DefaultConsolePaths = NextDevicePathStr; | |
| if (DefaultConsolePaths[0] == L';') { | |
| DefaultConsolePaths++; | |
| } | |
| } | |
| DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr); | |
| ASSERT(DevicePathInstance != NULL); | |
| DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance); | |
| if (NextDevicePathStr != NULL) { | |
| FreePool (DevicePathStr); | |
| } | |
| FreePool (DevicePathInstance); | |
| } | |
| // Set the environment variable with this device path multi-instances | |
| Size = GetDevicePathSize (DevicePathInstances); | |
| if (Size > 0) { | |
| gRT->SetVariable ( | |
| ConsoleVarName, | |
| &gEfiGlobalVariableGuid, | |
| EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
| Size, | |
| DevicePathInstances | |
| ); | |
| } else { | |
| Status = EFI_INVALID_PARAMETER; | |
| } | |
| } | |
| if (!EFI_ERROR(Status)) { | |
| *DevicePaths = DevicePathInstances; | |
| } | |
| return Status; | |
| } | |
| STATIC | |
| EFI_STATUS | |
| InitializeConsolePipe ( | |
| IN EFI_DEVICE_PATH *ConsoleDevicePaths, | |
| IN EFI_GUID *Protocol, | |
| OUT EFI_HANDLE *Handle, | |
| OUT VOID* *Interface | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN Size; | |
| UINTN NoHandles; | |
| EFI_HANDLE *Buffer; | |
| EFI_DEVICE_PATH_PROTOCOL* DevicePath; | |
| // Connect all the Device Path Consoles | |
| while (ConsoleDevicePaths != NULL) { | |
| DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size); | |
| Status = BdsLibConnectDevicePath (DevicePath); | |
| if (!EFI_ERROR (Status)) { | |
| // | |
| // If BdsLibConnectDevicePath () succeeded, *Handle must have a non-NULL | |
| // value. So ASSERT that this is the case. | |
| // | |
| gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, Handle); | |
| ASSERT (*Handle != NULL); | |
| } | |
| DEBUG_CODE_BEGIN(); | |
| if (EFI_ERROR(Status)) { | |
| // We convert back to the text representation of the device Path | |
| EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToTextProtocol; | |
| CHAR16 *DevicePathTxt; | |
| DevicePathToTextProtocol = NULL; | |
| gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevicePathToTextProtocol); | |
| if (DevicePathToTextProtocol != NULL) { | |
| DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE); | |
| DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status)); | |
| FreePool (DevicePathTxt); | |
| } | |
| } | |
| DEBUG_CODE_END(); | |
| // If the console splitter driver is not supported by the platform then use the first Device Path | |
| // instance for the console interface. | |
| if (!EFI_ERROR(Status) && (*Interface == NULL)) { | |
| Status = gBS->HandleProtocol (*Handle, Protocol, Interface); | |
| } | |
| } | |
| // No Device Path has been defined for this console interface. We take the first protocol implementation | |
| if (*Interface == NULL) { | |
| Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); | |
| if (EFI_ERROR (Status)) { | |
| BdsLibConnectAll (); | |
| Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); | |
| } | |
| if (!EFI_ERROR(Status)) { | |
| *Handle = Buffer[0]; | |
| Status = gBS->HandleProtocol (*Handle, Protocol, Interface); | |
| ASSERT_EFI_ERROR (Status); | |
| FreePool (Buffer); | |
| } | |
| } else { | |
| Status = EFI_SUCCESS; | |
| } | |
| return Status; | |
| } | |
| /** | |
| Connect the predefined platform default console device. Always try to find | |
| and enable the vga device if have. | |
| @param PlatformConsole Predefined platform default console device array. | |
| @retval EFI_SUCCESS Success connect at least one ConIn and ConOut | |
| device, there must have one ConOut device is | |
| active vga device. | |
| @return Return the status of BdsLibConnectAllDefaultConsoles () | |
| **/ | |
| EFI_STATUS | |
| PlatformBdsConnectConsole ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_DEVICE_PATH* ConOutDevicePaths; | |
| EFI_DEVICE_PATH* ConInDevicePaths; | |
| EFI_DEVICE_PATH* ConErrDevicePaths; | |
| // By getting the Console Device Paths from the environment variables before initializing the console pipe, we | |
| // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface | |
| // of newly installed console drivers | |
| Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths); | |
| ASSERT_EFI_ERROR (Status); | |
| // Initialize the Consoles | |
| Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr); | |
| if (EFI_ERROR(Status)) { | |
| // In case of error, we reuse the console output for the error output | |
| gST->StandardErrorHandle = gST->ConsoleOutHandle; | |
| gST->StdErr = gST->ConOut; | |
| } | |
| return Status; | |
| } | |
| /** | |
| Connect with predefined platform connect sequence, | |
| the OEM/IBV can customize with their own connect sequence. | |
| **/ | |
| VOID | |
| PlatformBdsConnectSequence ( | |
| VOID | |
| ) | |
| { | |
| } | |
| /** | |
| Load the predefined driver option, OEM/IBV can customize this | |
| to load their own drivers | |
| @param BdsDriverLists - The header of the driver option link list. | |
| **/ | |
| VOID | |
| PlatformBdsGetDriverOption ( | |
| IN OUT LIST_ENTRY *BdsDriverLists | |
| ) | |
| { | |
| } | |
| /** | |
| Perform the platform diagnostic, such like test memory. OEM/IBV also | |
| can customize this function to support specific platform diagnostic. | |
| @param MemoryTestLevel The memory test intensive level | |
| @param QuietBoot Indicate if need to enable the quiet boot | |
| @param BaseMemoryTest A pointer to BdsMemoryTest() | |
| **/ | |
| VOID | |
| PlatformBdsDiagnostics ( | |
| IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, | |
| IN BOOLEAN QuietBoot, | |
| IN BASEM_MEMORY_TEST BaseMemoryTest | |
| ) | |
| { | |
| } | |
| /** | |
| The function will execute with as the platform policy, current policy | |
| is driven by boot mode. IBV/OEM can customize this code for their specific | |
| policy action. | |
| @param DriverOptionList The header of the driver option link list | |
| @param BootOptionList The header of the boot option link list | |
| @param ProcessCapsules A pointer to ProcessCapsules() | |
| @param BaseMemoryTest A pointer to BaseMemoryTest() | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformBdsPolicyBehavior ( | |
| IN LIST_ENTRY *DriverOptionList, | |
| IN LIST_ENTRY *BootOptionList, | |
| IN PROCESS_CAPSULES ProcessCapsules, | |
| IN BASEM_MEMORY_TEST BaseMemoryTest | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = PlatformBdsConnectConsole (); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Show the splash screen. | |
| // | |
| EnableQuietBoot (PcdGetPtr (PcdLogoFile)); | |
| // | |
| // Connect _all_ devices, to pick up plug-in and removable devices | |
| // TODO: do this more cleanly, permitting faster boot times when boot config | |
| // is known | |
| // | |
| BdsLibConnectAll (); | |
| } | |
| /** | |
| Hook point after a boot attempt succeeds. We don't expect a boot option to | |
| return, so the UEFI 2.0 specification defines that you will default to an | |
| interactive mode and stop processing the BootOrder list in this case. This | |
| is also a platform implementation and can be customized by IBV/OEM. | |
| @param Option Pointer to Boot Option that succeeded to boot. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformBdsBootSuccess ( | |
| IN BDS_COMMON_OPTION *Option | |
| ) | |
| { | |
| } | |
| /** | |
| Hook point after a boot attempt fails. | |
| @param Option Pointer to Boot Option that failed to boot. | |
| @param Status Status returned from failed boot. | |
| @param ExitData Exit data returned from failed boot. | |
| @param ExitDataSize Exit data size returned from failed boot. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformBdsBootFail ( | |
| IN BDS_COMMON_OPTION *Option, | |
| IN EFI_STATUS Status, | |
| IN CHAR16 *ExitData, | |
| IN UINTN ExitDataSize | |
| ) | |
| { | |
| } | |
| /** | |
| This function locks platform flash that is not allowed to be updated during normal boot path. | |
| The flash layout is platform specific. | |
| **/ | |
| VOID | |
| EFIAPI | |
| PlatformBdsLockNonUpdatableFlash ( | |
| VOID | |
| ) | |
| { | |
| return; | |
| } | |
| /** | |
| Lock the ConsoleIn device in system table. All key | |
| presses will be ignored until the Password is typed in. The only way to | |
| disable the password is to type it in to a ConIn device. | |
| @param Password Password used to lock ConIn device. | |
| @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully. | |
| @retval EFI_UNSUPPORTED Password not found | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| LockKeyboards ( | |
| IN CHAR16 *Password | |
| ) | |
| { | |
| return EFI_UNSUPPORTED; | |
| } |