+++ /dev/null
-/** @file\r
- The entry of the embedded BDS. This BDS does not follow the Boot Manager requirements \r
- of the UEFI specification as it is designed to implement an embedded systmes \r
- propriatary boot scheme.\r
-\r
- This template assume a DXE driver produces a SerialIo protocol not using the EFI \r
- driver module and it will attempt to connect a console on top of this.\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- \r
- 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 "BdsEntry.h"\r
-\r
-\r
-BOOLEAN gConsolePresent = FALSE;\r
-\r
-\r
-EFI_HANDLE mBdsImageHandle = NULL;\r
-EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {\r
- BdsEntry,\r
-};\r
-\r
-\r
- \r
- \r
-/**\r
- This function uses policy data from the platform to determine what operating \r
- system or system utility should be loaded and invoked. This function call \r
- also optionally make the use of user input to determine the operating system \r
- or system utility to be loaded and invoked. When the DXE Core has dispatched \r
- all the drivers on the dispatch queue, this function is called. This \r
- function will attempt to connect the boot devices required to load and invoke \r
- the selected operating system or system utility. During this process, \r
- additional firmware volumes may be discovered that may contain addition DXE \r
- drivers that can be dispatched by the DXE Core. If a boot device cannot be \r
- fully connected, this function calls the DXE Service Dispatch() to allow the \r
- DXE drivers from any newly discovered firmware volumes to be dispatched. \r
- Then the boot device connection can be attempted again. If the same boot \r
- device connection operation fails twice in a row, then that boot device has \r
- failed, and should be skipped. This function should never return.\r
-\r
- @param This The EFI_BDS_ARCH_PROTOCOL instance.\r
-\r
- @return None.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BdsEntry (\r
- IN EFI_BDS_ARCH_PROTOCOL *This\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN NoHandles;\r
- EFI_HANDLE *Buffer;\r
- EFI_HANDLE FvHandle;\r
- EFI_HANDLE ImageHandle;\r
- EFI_HANDLE UsbDeviceHandle;\r
- EFI_GUID NameGuid;\r
- UINTN Size;\r
- UINTN HandleCount;\r
- UINTN OldHandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *LoadImageDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *FileSystemDevicePath;\r
- \r
- PERF_END (NULL, "DXE", NULL, 0);\r
- PERF_START (NULL, "BDS", NULL, 0);\r
-\r
-\r
- //\r
- // Now do the EFI stuff\r
- //\r
- Size = 0x100;\r
- gST->FirmwareVendor = AllocateRuntimePool (Size);\r
- ASSERT (gST->FirmwareVendor != NULL);\r
- \r
- UnicodeSPrint (gST->FirmwareVendor, Size, L"BeagleBoard EFI %a %a", __DATE__, __TIME__);\r
-\r
- //\r
- // Now we need to setup the EFI System Table with information about the console devices.\r
- // This code is normally in the console spliter driver on platforms that support multiple \r
- // consoles at the same time\r
- //\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &NoHandles, &Buffer);\r
- if (!EFI_ERROR (Status)) {\r
- // Use the first SimpleTextOut we find and update the EFI System Table\r
- gST->ConsoleOutHandle = Buffer[0];\r
- gST->StandardErrorHandle = Buffer[0];\r
- Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextOutProtocolGuid, (VOID **)&gST->ConOut);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- gST->StdErr = gST->ConOut;\r
- \r
- gST->ConOut->OutputString (gST->ConOut, L"BDS: Console Started!!!!\n\r");\r
- FreePool (Buffer);\r
- \r
- gConsolePresent = TRUE;\r
- } \r
- \r
-\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextInProtocolGuid, NULL, &NoHandles, &Buffer);\r
- if (!EFI_ERROR (Status)) {\r
- // Use the first SimpleTextIn we find and update the EFI System Table\r
- gST->ConsoleInHandle = Buffer[0];\r
- Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextInProtocolGuid, (VOID **)&gST->ConIn);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- FreePool (Buffer);\r
- }\r
-\r
- //\r
- // We now have EFI Consoles up and running. Print () will work now. DEBUG () and ASSERT () worked \r
- // prior to this point as they were configured to use a more primative output scheme.\r
- //\r
-\r
- //\r
- //Perform Connect\r
- //\r
- HandleCount = 0;\r
- while (1) {\r
- OldHandleCount = HandleCount;\r
- Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- \r
- if (HandleCount == OldHandleCount) {\r
- break;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
- }\r
- }\r
-\r
- EfiSignalEventReadyToBoot ();\r
-\r
- //Locate handles for SimpleFileSystem protocol\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- //Get the device path\r
- FileSystemDevicePath = DevicePathFromHandle(HandleBuffer[Index]);\r
- if (FileSystemDevicePath == NULL) {\r
- continue;\r
- }\r
-\r
- //Check if UsbIo is on any handles in the device path.\r
- Status = gBS->LocateDevicePath(&gEfiUsbIoProtocolGuid, &FileSystemDevicePath, &UsbDeviceHandle);\r
- if (EFI_ERROR(Status)) {\r
- continue;\r
- }\r
-\r
- //Check if Usb stick has a magic EBL file.\r
- LoadImageDevicePath = FileDevicePath(HandleBuffer[Index], L"Ebl.efi");\r
- Status = gBS->LoadImage (TRUE, gImageHandle, LoadImageDevicePath, NULL, 0, &ImageHandle);\r
- if (EFI_ERROR(Status)) {\r
- continue;\r
- }\r
-\r
- //Boot to Shell on USB stick.\r
- Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
- if (EFI_ERROR(Status)) {\r
- continue;\r
- }\r
- }\r
- }\r
- \r
- //\r
- // Normal UEFI behavior is to process Globally Defined Variables as defined in Chapter 3 \r
- // (Boot Manager) of the UEFI specification. For this embedded system we don't do this.\r
- //\r
-\r
- //\r
- // Search all the FVs for an application with a UI Section of Ebl. A .FDF file can be used\r
- // to control the names of UI sections in an FV.\r
- //\r
- Status = FindApplicationMatchingUiSection (L"Ebl", &FvHandle, &NameGuid);\r
- if (!EFI_ERROR (Status)) {\r
-\r
- //Boot to Shell.\r
- Status = LoadPeCoffSectionFromFv (FvHandle, &NameGuid);\r
-\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "Boot from Shell failed. Status: %r\n", Status));\r
- }\r
- }\r
-\r
- //\r
- // EFI does not define the behaviour if all boot attemps fail and the last one returns. \r
- // So we make a policy choice to reset the system since this BDS does not have a UI.\r
- //\r
- gRT->ResetSystem (EfiResetShutdown, Status, 0, NULL);\r
-\r
- return ;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BdsInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- mBdsImageHandle = ImageHandle;\r
-\r
- //\r
- // Install protocol interface\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mBdsImageHandle,\r
- &gEfiBdsArchProtocolGuid, &gBdsProtocol,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-\r