summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/Bds
diff options
context:
space:
mode:
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-02-01 05:41:42 +0000
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-02-01 05:41:42 +0000
commit1d5d0ae92d95410f20bc6daab7a47e129fb2547a (patch)
tree8679c57c5f85cadad47d4604450c1c3702276cf1 /ArmPlatformPkg/Bds
parentfb334ef6c543b1babc9d8a613ad5d1ce6fe536e1 (diff)
downloadedk2-platforms-1d5d0ae92d95410f20bc6daab7a47e129fb2547a.tar.xz
Add ArmPlatformPkg from ARM Ltd. patch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11291 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Bds')
-rw-r--r--ArmPlatformPkg/Bds/Bds.inf53
-rw-r--r--ArmPlatformPkg/Bds/BdsEntry.c310
2 files changed, 363 insertions, 0 deletions
diff --git a/ArmPlatformPkg/Bds/Bds.inf b/ArmPlatformPkg/Bds/Bds.inf
new file mode 100644
index 0000000000..dbd26aedb4
--- /dev/null
+++ b/ArmPlatformPkg/Bds/Bds.inf
@@ -0,0 +1,53 @@
+#/** @file
+#
+# Component discription file for NorFlashDxe module
+#
+# Copyright (c) 2010, 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.
+#
+#**/
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformBds
+ FILE_GUID = 5a50aa81-c3ae-4608-a0e3-41a2e69baf94
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = BdsInitialize
+
+[Sources.common]
+ BdsEntry.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BdsLib
+ TimerLib
+ PerformanceLib
+ UefiBootServicesTableLib
+ DebugLib
+
+[Guids]
+
+[Protocols]
+ gEfiBdsArchProtocolGuid
+ gEfiSimpleTextInProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdLinuxKernelDP
+ gArmTokenSpaceGuid.PcdLinuxAtag
+ gArmTokenSpaceGuid.PcdFdtDP
+
+[Depex]
+ TRUE
diff --git a/ArmPlatformPkg/Bds/BdsEntry.c b/ArmPlatformPkg/Bds/BdsEntry.c
new file mode 100644
index 0000000000..d126710df1
--- /dev/null
+++ b/ArmPlatformPkg/Bds/BdsEntry.c
@@ -0,0 +1,310 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* 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 <PiDxe.h>
+#include <Library/BdsLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+
+#include <Protocol/Bds.h>
+#include <Protocol/DevicePathToText.h>
+
+#include <Guid/GlobalVariable.h>
+
+#define MAX_CMD_LINE 256
+
+VOID
+EFIAPI
+BdsEntry (
+ IN EFI_BDS_ARCH_PROTOCOL *This
+ );
+
+EFI_HANDLE mBdsImageHandle = NULL;
+EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {
+ BdsEntry,
+};
+
+EFI_STATUS GetEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN VOID* DefaultValue,
+ IN UINTN DefaultSize,
+ OUT VOID** Value)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+ // Try to get the variable size.
+ *Value = NULL;
+ Size = 0;
+ Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &Size, *Value);
+ if (Status == EFI_NOT_FOUND) {
+ // If the environment variable does not exist yet then set it with the default value
+ Status = gRT->SetVariable (
+ (CHAR16*)VariableName,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DefaultSize,
+ DefaultValue
+ );
+ *Value = DefaultValue;
+ } else if (Status == EFI_BUFFER_TOO_SMALL) {
+ // Get the environment variable value
+ *Value = AllocatePool (Size);
+ if (*Value == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, *Value);
+ if (EFI_ERROR (Status)) {
+ FreePool(*Value);
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ *Value = DefaultValue;
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID InitializeConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN NoHandles;
+ EFI_HANDLE *Buffer;
+
+ //
+ // Now we need to setup the EFI System Table with information about the console devices.
+ // This code is normally in the console spliter driver on platforms that support multiple
+ // consoles at the same time
+ //
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &NoHandles, &Buffer);
+ if (!EFI_ERROR (Status)) {
+ // Use the first SimpleTextOut we find and update the EFI System Table
+ gST->ConsoleOutHandle = Buffer[0];
+ gST->StandardErrorHandle = Buffer[0];
+ Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextOutProtocolGuid, (VOID **)&gST->ConOut);
+ ASSERT_EFI_ERROR (Status);
+
+ gST->StdErr = gST->ConOut;
+
+ FreePool (Buffer);
+ }
+
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextInProtocolGuid, NULL, &NoHandles, &Buffer);
+ if (!EFI_ERROR (Status)) {
+ // Use the first SimpleTextIn we find and update the EFI System Table
+ gST->ConsoleInHandle = Buffer[0];
+ Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextInProtocolGuid, (VOID **)&gST->ConIn);
+ ASSERT_EFI_ERROR (Status);
+
+ FreePool (Buffer);
+ }
+}
+
+EFI_STATUS
+GetHIInputAscii (
+ CHAR8 *CmdLine,
+ UINTN MaxCmdLine
+) {
+ UINTN CmdLineIndex;
+ UINTN WaitIndex;
+ CHAR8 Char;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ CmdLine[0] = '\0';
+
+ for (CmdLineIndex = 0; CmdLineIndex < MaxCmdLine; ) {
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR (Status);
+
+ Char = (CHAR8)Key.UnicodeChar;
+ if ((Char == '\n') || (Char == '\r') || (Char == 0x7f)) {
+ CmdLine[CmdLineIndex] = '\0';
+ AsciiPrint ("\n");
+ return EFI_SUCCESS;
+ } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
+ if (CmdLineIndex != 0) {
+ CmdLineIndex--;
+ AsciiPrint ("\b \b");
+ }
+ } else {
+ CmdLine[CmdLineIndex++] = Char;
+ AsciiPrint ("%c", Char);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+ListDevicePaths (
+ IN BOOLEAN AllDrivers
+) {
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
+ CHAR16* String;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* EfiDevicePathToTextProtocol;
+
+ if (AllDrivers) {
+ BdsConnectAllDrivers();
+ }
+
+ Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&EfiDevicePathToTextProtocol);
+ if (EFI_ERROR (Status)) {
+ AsciiPrint ("Did not find the DevicePathToTextProtocol.\n");
+ return;
+ }
+
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &HandleCount, &HandleBuffer);
+ if (EFI_ERROR (Status)) {
+ AsciiPrint ("No device path found\n");
+ return;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
+ String = EfiDevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE);
+ Print (L"\t- [%d] %s\n",Index, String);
+ }
+}
+
+INTN BdsComparefile (
+ IN CHAR16 *DeviceFilePath1,
+ IN CHAR16 *DeviceFilePath2,
+ VOID **FileImage1,VOID **FileImage2,UINTN* FileSize
+ );
+
+/**
+ This function uses policy data from the platform to determine what operating
+ system or system utility should be loaded and invoked. This function call
+ also optionally make the use of user input to determine the operating system
+ or system utility to be loaded and invoked. When the DXE Core has dispatched
+ all the drivers on the dispatch queue, this function is called. This
+ function will attempt to connect the boot devices required to load and invoke
+ the selected operating system or system utility. During this process,
+ additional firmware volumes may be discovered that may contain addition DXE
+ drivers that can be dispatched by the DXE Core. If a boot device cannot be
+ fully connected, this function calls the DXE Service Dispatch() to allow the
+ DXE drivers from any newly discovered firmware volumes to be dispatched.
+ Then the boot device connection can be attempted again. If the same boot
+ device connection operation fails twice in a row, then that boot device has
+ failed, and should be skipped. This function should never return.
+
+ @param This The EFI_BDS_ARCH_PROTOCOL instance.
+
+ @return None.
+
+**/
+VOID
+EFIAPI
+BdsEntry (
+ IN EFI_BDS_ARCH_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 CmdLine[MAX_CMD_LINE];
+ VOID* DefaultVariableValue;
+ UINTN DefaultVariableSize;
+ CHAR16 *LinuxKernelDP;
+ CHAR8 *LinuxAtag;
+ CHAR16 *FdtDP;
+
+ PERF_END (NULL, "DXE", NULL, 0);
+ PERF_START (NULL, "BDS", NULL, 0);
+
+ InitializeConsole();
+
+ while (1) {
+ // Get the Linux Kernel Device Path from Environment Variable
+ DefaultVariableValue = (VOID*)PcdGetPtr(PcdLinuxKernelDP);
+ DefaultVariableSize = StrSize((CHAR16*)DefaultVariableValue);
+ GetEnvironmentVariable(L"LinuxKernelDP",DefaultVariableValue,DefaultVariableSize,(VOID**)&LinuxKernelDP);
+
+ // Get the Linux ATAG from Environment Variable
+ DefaultVariableValue = (VOID*)PcdGetPtr(PcdLinuxAtag);
+ DefaultVariableSize = AsciiStrSize((CHAR8*)DefaultVariableValue);
+ GetEnvironmentVariable(L"LinuxAtag",DefaultVariableValue,DefaultVariableSize,(VOID**)&LinuxAtag);
+
+ // Get the FDT Device Path from Environment Variable
+ DefaultVariableValue = (VOID*)PcdGetPtr(PcdFdtDP);
+ DefaultVariableSize = StrSize((CHAR16*)DefaultVariableValue);
+ GetEnvironmentVariable(L"FdtDP",DefaultVariableValue,DefaultVariableSize,(VOID**)&FdtDP);
+
+ AsciiPrint ("1. Start EBL\n\r");
+ AsciiPrint ("2. List Device Paths of all the drivers\n");
+ AsciiPrint ("3. Start Linux\n");
+ Print (L"\t- Kernel: %s\n", LinuxKernelDP);
+ AsciiPrint ("\t- Atag: %a\n", LinuxAtag);
+ Print (L"\t- Fdt: %s\n", FdtDP);
+ AsciiPrint ("Choice: ");
+
+ Status = GetHIInputAscii(CmdLine,MAX_CMD_LINE);
+ ASSERT_EFI_ERROR (Status);
+ if (AsciiStrCmp(CmdLine,"1") == 0) {
+ // Start EBL
+ Status = BdsLoadApplication(L"Ebl");
+ if (Status == EFI_NOT_FOUND) {
+ AsciiPrint ("Error: EFI Application not found.\n");
+ } else {
+ AsciiPrint ("Error: Status Code: 0x%X\n",(UINT32)Status);
+ }
+ } else if (AsciiStrCmp(CmdLine,"2") == 0) {
+ ListDevicePaths (TRUE);
+ } else if (AsciiStrCmp(CmdLine,"3") == 0) {
+ // Start Linux Kernel
+ Status = BdsBootLinux(LinuxKernelDP,LinuxAtag,FdtDP);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint ("Error: Fail to start Linux (0x%X)\n",(UINT32)Status);
+ }
+ } else {
+ AsciiPrint ("Error: Invalid choice.\n");
+ }
+ }
+}
+
+EFI_STATUS
+EFIAPI
+BdsInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mBdsImageHandle = ImageHandle;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mBdsImageHandle,
+ &gEfiBdsArchProtocolGuid, &gBdsProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}