hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/CmdTemplate.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/CmdTemplate.c
new file mode 100644
index 0000000..2c291fc
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/CmdTemplate.c
@@ -0,0 +1,65 @@
+/** @file

+  %CommandName% for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. 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.

+

+  Module Name:  CmdTemplate.c

+

+  Search/Replace %CommandName% with the name of your new command

+

+**/

+

+#include "Ebl.h"

+

+

+/**

+  Fill Me In

+

+  Argv[0] - "%CommandName%"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+Ebl%CommandName%Cmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  return EFI_SUCCESS;

+}

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmd%CommandName%Template[] =

+{

+  {

+    "%CommandName%",

+    " [show args] ; explain args and command",

+    NULL,

+    Ebl%CommandName%Cmd

+  }

+};

+

+

+/**

+  Initialize the commands in this file

+**/

+VOID

+EblInitialize%CommandName%Cmd (

+  VOID

+  )

+{

+  EblAddCommands (mCmd%CommandName%Template, sizeof (mCmd%CommandName%Template)/sizeof (EBL_COMMAND_TABLE));

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Command.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Command.c
new file mode 100644
index 0000000..04ea794
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Command.c
@@ -0,0 +1,916 @@
+/** @file

+  Basic commands and command processing infrastructure for EBL

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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 "Ebl.h"

+#include <Protocol/DiskIo.h>

+#include <Protocol/BlockIo.h>

+

+UINTN             mCmdTableMaxIndex = EBL_MAX_COMMAND_COUNT;

+UINTN             mCmdTableNextFreeIndex = 0;

+EBL_COMMAND_TABLE *mCmdTable[EBL_MAX_COMMAND_COUNT];

+

+/**

+  Converts a lowercase Ascii character to upper one

+

+  If Chr is lowercase Ascii character, then converts it to upper one.

+

+  If Value >= 0xA0, then ASSERT().

+  If (Value & 0x0F) >= 0x0A, then ASSERT().

+

+  @param  chr   one Ascii character

+

+  @return The uppercase value of Ascii character

+

+**/

+STATIC

+CHAR8

+AsciiToUpper (

+  IN      CHAR8                     Chr

+  )

+{

+  return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);

+}

+

+

+/**

+  Case insensitive comparison of two Null-terminated Unicode strings with maximum

+  lengths, and returns the difference between the first mismatched Unicode

+  characters.

+  This function compares the Null-terminated Unicode string FirstString to the

+  Null-terminated Unicode string SecondString. At most, Length Unicode

+  characters will be compared. If Length is 0, then 0 is returned. If

+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the

+  value returned is the first mismatched Unicode character in SecondString

+  subtracted from the first mismatched Unicode character in FirstString.

+

+  @param  FirstString   Pointer to a Null-terminated ASCII string.

+  @param  SecondString  Pointer to a Null-terminated ASCII string.

+  @param  Length        Max length to compare.

+

+  @retval 0   FirstString is identical to SecondString using case insensitive

+              comparisons.

+  @retval !=0 FirstString is not identical to SecondString using case

+              insensitive comparisons.

+

+**/

+INTN

+EFIAPI

+AsciiStrniCmp (

+  IN      CONST CHAR8               *FirstString,

+  IN      CONST CHAR8               *SecondString,

+  IN      UINTN                     Length

+  )

+{

+  if (Length == 0) {

+    return 0;

+  }

+

+  while ((AsciiToUpper (*FirstString) != '\0') &&

+         (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString)) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+

+  return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);

+}

+

+

+

+/**

+  Add a command to the mCmdTable. If there is no free space in the command

+  table ASSERT. The mCmdTable is maintained in alphabetical order and the

+  new entry is inserted into its sorted position.

+

+  @param  Entry   Command Entry to add to the CmdTable

+

+**/

+VOID

+EFIAPI

+EblAddCommand (

+  IN const EBL_COMMAND_TABLE   *Entry

+  )

+{

+  UINTN               Count;

+

+  if (mCmdTableNextFreeIndex == EBL_MAX_COMMAND_COUNT) {

+    //

+    // Ran out of space to store commands. Increase EBL_MAX_COMMAND_COUNT

+    //

+    ASSERT (FALSE);

+    return;

+  }

+

+  //

+  // Add command and Insertion sort array in the process

+  //

+  mCmdTable[mCmdTableNextFreeIndex] = (EBL_COMMAND_TABLE *)Entry;

+  if (mCmdTableNextFreeIndex != 0) {

+    for (Count = mCmdTableNextFreeIndex; Count > 0; Count--) {

+      if (AsciiStriCmp (mCmdTable[Count - 1]->Name, Entry->Name) <= 0) {

+        break;

+      }

+

+      mCmdTable[Count] = mCmdTable[Count - 1];

+    }

+    mCmdTable[Count] = (EBL_COMMAND_TABLE *)Entry;

+  }

+

+  mCmdTableNextFreeIndex++;

+}

+

+

+/**

+  Add an set of commands to the command table. Most commonly used on static

+  array of commands.

+

+  @param  EntryArray   Pointer to array of command entries

+  @param  ArrayCount   Number of command entries to add

+

+**/

+VOID

+EFIAPI

+EblAddCommands (

+  IN const EBL_COMMAND_TABLE   *EntryArray,

+  IN UINTN                     ArrayCount

+  )

+{

+  UINTN   Index;

+

+  for (Index = 0; Index < ArrayCount; Index++) {

+    EblAddCommand (&EntryArray[Index]);

+  }

+}

+

+

+EBL_ADD_COMMAND_PROTOCOL gEblAddCommand = {

+  EblAddCommand,

+  EblAddCommands,

+  EblGetCharKey,

+  EblAnyKeyToContinueQtoQuit

+};

+

+

+

+/**

+  Return the best matching command for the passed in command name. The match

+  does not have to be exact, it just needs to be unique. This enables commands

+  to be shortened to the smallest set of starting characters that is unique.

+

+  @param  CommandName   Name of command to search for

+

+  @return NULL  CommandName did not match or was not unique

+          Other Pointer to EBL_COMMAND_TABLE entry for CommandName

+

+**/

+EBL_COMMAND_TABLE *

+EblGetCommand (

+  IN CHAR8    *CommandName

+  )

+{

+  UINTN               Index;

+  UINTN               BestMatchCount;

+  UINTN               Length;

+  EBL_COMMAND_TABLE   *Match;

+  CHAR8               *Str;

+

+  Length = AsciiStrLen (CommandName);

+  Str = AsciiStrStr (CommandName, ".");

+  if (Str != NULL) {

+    // If the command includes a trailing . command extension skip it for the match.

+    // Example: hexdump.4

+    Length = (UINTN)(Str - CommandName);

+  }

+

+  for (Index = 0, BestMatchCount = 0, Match = NULL; Index < mCmdTableNextFreeIndex; Index++) {

+    if (AsciiStriCmp (mCmdTable[Index]->Name,  CommandName) == 0) {

+      // match a command exactly

+      return mCmdTable[Index];

+    }

+

+    if (AsciiStrniCmp (CommandName, mCmdTable[Index]->Name, Length) == 0)  {

+      // partial match, so keep looking to make sure there is only one partial match

+      BestMatchCount++;

+      Match = mCmdTable[Index];

+    }

+  }

+

+  if (BestMatchCount == 1) {

+    return Match;

+  }

+

+  //

+  // We had no matches or too many matches

+  //

+  return NULL;

+}

+

+

+UINTN

+CountNewLines (

+  IN CHAR8  *Str

+  )

+{

+  UINTN Count;

+

+  if (Str == NULL) {

+    return 0;

+  }

+

+  for (Count = 0; *Str != '\0'; Str++) {

+    if (Str[Count] == '\n') {

+      Count++;

+    }

+  }

+

+  return Count;

+}

+

+

+/**

+  List out help information on all the commands or print extended information

+  about a specific passed in command.

+

+  Argv[0] - "help"

+  Argv[1] - Command to display help about

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblHelpCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN   Index;

+  CHAR8   *Ptr;

+  UINTN   CurrentRow = 0;

+

+  if (Argc == 1) {

+    // Print all the commands

+    AsciiPrint ("Embedded Boot Loader (EBL) commands (help command for more info):\n");

+    CurrentRow++;

+    for (Index = 0; Index < mCmdTableNextFreeIndex; Index++) {

+      EblSetTextColor (EFI_YELLOW);

+      AsciiPrint (" %a", mCmdTable[Index]->Name);

+      EblSetTextColor (0);

+      AsciiPrint ("%a\n", mCmdTable[Index]->HelpSummary);

+      // Handle multi line help summaries

+      CurrentRow += CountNewLines (mCmdTable[Index]->HelpSummary);

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+        break;

+      }

+    }

+  } else if (Argv[1] != NULL) {

+    // Print specific help

+    for (Index = 0, CurrentRow = 0; Index < mCmdTableNextFreeIndex; Index++) {

+      if (AsciiStriCmp (Argv[1], mCmdTable[Index]->Name) == 0) {

+        Ptr = (mCmdTable[Index]->Help == NULL) ? mCmdTable[Index]->HelpSummary : mCmdTable[Index]->Help;

+        AsciiPrint ("%a%a\n", Argv[1], Ptr);

+        // Handle multi line help summaries

+        CurrentRow += CountNewLines (Ptr);

+        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+          break;

+        }

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Exit the EBL. If the command processor sees EFI_ABORTED return status it will

+  exit the EBL.

+

+  Argv[0] - "exit"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_ABORTED

+

+**/

+EFI_STATUS

+EblExitCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS              Status;

+  UINTN                   MemoryMapSize;

+  EFI_MEMORY_DESCRIPTOR   *MemoryMap;

+  UINTN                   MapKey;

+  UINTN                   DescriptorSize;

+  UINT32                  DescriptorVersion;

+  UINTN                   Pages;

+

+  if (Argc > 1) {

+    if (AsciiStriCmp (Argv[1], "efi") != 0) {

+      return EFI_ABORTED;

+    }

+  } else if (Argc == 1) {

+    return EFI_ABORTED;

+  }

+

+  MemoryMap = NULL;

+  MemoryMapSize = 0;

+  do {

+    Status = gBS->GetMemoryMap (

+                    &MemoryMapSize,

+                    MemoryMap,

+                    &MapKey,

+                    &DescriptorSize,

+                    &DescriptorVersion

+                    );

+    if (Status == EFI_BUFFER_TOO_SMALL) {

+

+      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;

+      MemoryMap = AllocatePages (Pages);

+

+      //

+      // Get System MemoryMap

+      //

+      Status = gBS->GetMemoryMap (

+                      &MemoryMapSize,

+                      MemoryMap,

+                      &MapKey,

+                      &DescriptorSize,

+                      &DescriptorVersion

+                      );

+      // Don't do anything between the GetMemoryMap() and ExitBootServices()

+      if (!EFI_ERROR (Status)) {

+        Status = gBS->ExitBootServices (gImageHandle, MapKey);

+        if (EFI_ERROR (Status)) {

+          FreePages (MemoryMap, Pages);

+          MemoryMap = NULL;

+          MemoryMapSize = 0;

+        }

+      }

+    }

+  } while (EFI_ERROR (Status));

+

+  //

+  // At this point it is very dangerous to do things EFI as most of EFI is now gone.

+  // This command is useful if you are working with a debugger as it will shutdown

+  // DMA and other things that could break a soft resets.

+  //

+  CpuDeadLoop ();

+

+  // Should never get here, but makes the compiler happy

+  return EFI_ABORTED;

+}

+

+

+/**

+  Update the screen by decrementing the timeout value.

+  This AsciiPrint has to match the AsciiPrint in

+  EblPauseCmd.

+

+  @param  ElaspedTime   Current timeout value remaining

+

+**/

+VOID

+EFIAPI

+EblPauseCallback (

+  IN  UINTN   ElapsedTime

+  )

+{

+  AsciiPrint ("\b\b\b\b\b\b\b\b\b\b\b\b   \b\b%3d seconds", ElapsedTime);

+}

+

+/**

+  Pause until a key is pressed and abort the remaining commands on the command

+  line. If no key is pressed continue processing the command line. This command

+  allows the user to stop an operation from happening and return control to the

+  command prompt.

+

+  Argv[0] - "pause"

+  Argv[1] - timeout value is decimal seconds

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS  Timeout expired with no input

+  @return EFI_TIMEOUT  Stop processing other commands on the same command line

+

+**/

+EFI_STATUS

+EblPauseCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS      Status;

+  UINTN           Delay;

+  EFI_INPUT_KEY   Key;

+

+  Delay = (Argc == 1)? 10 : AsciiStrDecimalToUintn (Argv[1]);

+

+  AsciiPrint ("Hit any key to break. You have %3d seconds", Delay);

+  Status = EblGetCharKey (&Key, Delay, EblPauseCallback);

+  AsciiPrint ("\n");

+

+  // If we timeout then the pause succeeded thus return success

+  // If we get a key return timeout to stop other command on this cmd line

+  return (Status == EFI_SUCCESS) ? EFI_TIMEOUT : EFI_SUCCESS;;

+}

+

+

+/**

+  On a debug build issue a software breakpoint to enter the debugger

+

+  Argv[0] - "break"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblBreakPointCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  CpuBreakpoint ();

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Reset the system. If no Argument do a Cold reset. If argument use that reset type

+  (W)arm = Warm Reset

+  (S)hutdown = Shutdown Reset

+

+  Argv[0] - "reset"

+  Argv[1] - warm or shutdown reset type

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblResetCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_RESET_TYPE    ResetType;

+

+  ResetType = EfiResetCold;

+  if (Argc > 1) {

+    switch (*Argv[1]) {

+    case 'W':

+    case 'w':

+      ResetType = EfiResetWarm;

+      break;

+    case 'S':

+    case 's':

+      ResetType = EfiResetShutdown;

+    }

+  }

+

+  gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Toggle page break global. This turns on and off prompting to Quit or hit any

+  key to continue when a command is about to scroll the screen with its output

+

+  Argv[0] - "page"

+  Argv[1] - on or off

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblPageCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  if (Argc <= 1) {

+    // toggle setting

+    gPageBreak = (gPageBreak) ? FALSE : TRUE;

+  } else {

+    // use argv to set the value

+    if ((Argv[1][0] == 'o') || (Argv[1][0] == 'O')) {

+      if ((Argv[1][1] == 'n') || (Argv[1][1] == 'N')) {

+        gPageBreak = TRUE;

+      } else if ((Argv[1][1] == 'f') || (Argv[1][1] == 'F')) {

+        gPageBreak = FALSE;

+      } else {

+        return EFI_INVALID_PARAMETER;

+      }

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EblSleepCmd (

+  IN UINTN Argc,

+  IN CHAR8 **Argv

+  )

+{

+  UINTN Delay;

+

+  Delay = (Argc == 1)? 10 : AsciiStrDecimalToUintn (Argv[1]);

+

+  gBS->Stall (Delay * 1000000);

+

+  return EFI_SUCCESS;

+}

+

+CHAR8

+ConvertToTextLine (

+  IN CHAR8  Character

+  )

+{

+  if (Character < ' ' || Character > '~') {

+    return '.';

+  } else {

+    return Character;

+  }

+}

+

+UINTN

+GetBytes (

+  IN UINT8  *Address,

+  IN UINTN  Bytes

+  )

+{

+  UINTN Result = 0;

+

+  if (Bytes >= 1) {

+    Result = *Address++;

+  }

+  if (Bytes >= 2) {

+    Result = (Result << 8) + *Address++;

+  }

+  if (Bytes >= 3) {

+    Result = (Result << 8) + *Address++;

+  }

+  return Result;

+}

+

+CHAR8 mBlanks[] = "                                           ";

+

+EFI_STATUS

+OutputData (

+  IN UINT8  *Address,

+  IN UINTN  Length,

+  IN UINTN  Width,

+  IN UINTN  Offset

+  )

+{

+  UINT8 *EndAddress;

+  UINTN Line;

+  CHAR8 TextLine[0x11];

+  UINTN CurrentRow = 0;

+  UINTN Bytes;

+  UINTN Spaces   = 0;

+  CHAR8 Blanks[80];

+

+  AsciiStrCpy (Blanks, mBlanks);

+  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line) {

+    AsciiPrint ("%08x: ", Offset);

+    for (Line = 0; (Line < 0x10) && (Address < EndAddress);) {

+      Bytes = EndAddress - Address;

+

+      switch (Width) {

+        case 4:

+          if (Bytes >= 4) {

+            AsciiPrint ("%08x ", *((UINT32 *)Address));

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+          } else {

+            AsciiPrint ("%08x ", GetBytes(Address, Bytes));

+            Address += Bytes;

+            Line    += Bytes;

+          }

+          break;

+

+        case 2:

+          if (Bytes >= 2) {

+            AsciiPrint ("%04x ", *((UINT16 *)Address));

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+            TextLine[Line++] = ConvertToTextLine(*Address++);

+          } else {

+            AsciiPrint ("%04x ", GetBytes(Address, Bytes));

+            Address += Bytes;

+            Line    += Bytes;

+          }

+          break;

+

+        case 1:

+          AsciiPrint ("%02x ", *((UINT8 *)Address));

+          TextLine[Line++] = ConvertToTextLine(*Address++);

+          break;

+

+        default:

+          AsciiPrint ("Width must be 1, 2, or 4!\n");

+          return EFI_INVALID_PARAMETER;

+      }

+    }

+

+    // Pad spaces

+    if (Line < 0x10) {

+      switch (Width) {

+        case 4:

+          Spaces = 9 * ((0x10 - Line)/4);

+          break;

+        case 2:

+          Spaces = 5 * ((0x10 - Line)/2);

+          break;

+        case 1:

+          Spaces = 3 * (0x10 - Line);

+          break;

+      }

+

+      Blanks[Spaces] = '\0';

+

+      AsciiPrint(Blanks);

+

+      Blanks[Spaces] = ' ';

+    }

+

+    TextLine[Line] = 0;

+    AsciiPrint ("|%a|\n", TextLine);

+

+    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+      return EFI_END_OF_FILE;

+    }

+  }

+

+  if (Length % Width != 0) {

+    AsciiPrint ("%08x\n", Offset);

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  See if command contains .# where # is a number. Return # as the Width

+  or 1 as the default Width for commands.

+

+  Example hexdump.4 returns a width of 4.

+

+  @param  Argv   Argv[0] is the command name

+

+  @return Width of command

+

+**/

+UINTN

+WidthFromCommandName (

+  IN CHAR8  *Argv,

+  IN UINTN  Default

+  )

+{

+  CHAR8         *Str;

+  UINTN         Width;

+

+  //Hexdump.2 HexDump.4 mean use a different width

+  Str = AsciiStrStr (Argv, ".");

+  if (Str != NULL) {

+    Width = AsciiStrDecimalToUintn (Str + 1);

+    if (Width == 0) {

+      Width = Default;

+    }

+  } else {

+    // Default answer

+    return Default;

+  }

+

+  return Width;

+}

+

+#define HEXDUMP_CHUNK 1024

+

+/**

+  Toggle page break global. This turns on and off prompting to Quit or hit any

+  key to continue when a command is about to scroll the screen with its output

+

+  Argv[0] - "hexdump"[.#]  # is optional 1,2, or 4 for width

+  Argv[1] - Device or File to dump.

+  Argv[2] - Optional offset to start dumping

+  Argv[3] - Optional number of bytes to dump

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblHexdumpCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_OPEN_FILE *File;

+  VOID          *Location;

+  UINTN         Size;

+  UINTN         Width;

+  UINTN         Offset = 0;

+  EFI_STATUS    Status;

+  UINTN         Chunk = HEXDUMP_CHUNK;

+

+  if ((Argc < 2) || (Argc > 4)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Width = WidthFromCommandName (Argv[0], 1);

+  if ((Width != 1) && (Width != 2) && (Width != 4)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    return EFI_NOT_FOUND;

+  }

+

+  Location = AllocatePool (Chunk);

+  Size     = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : EfiTell (File, NULL);

+

+  Offset = 0;

+  if (Argc > 2) {

+    Offset = AsciiStrHexToUintn (Argv[2]);

+    if (Offset > 0) {

+      // Make sure size includes the part of the file we have skipped

+      Size += Offset;

+    }

+  }

+

+  Status = EfiSeek (File, Offset, EfiSeekStart);

+  if (EFI_ERROR (Status)) {

+    goto Exit;

+  }

+

+  for (; Offset + HEXDUMP_CHUNK <= Size; Offset += Chunk) {

+    Chunk = HEXDUMP_CHUNK;

+    Status = EfiRead (File, Location, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint ("Error reading file content\n");

+      goto Exit;

+    }

+

+    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);

+    if (EFI_ERROR(Status)) {

+      if (Status == EFI_END_OF_FILE) {

+        Status = EFI_SUCCESS;

+      }

+      goto Exit;

+    }

+  }

+

+  // Any left over?

+  if (Offset < Size) {

+    Chunk = Size - Offset;

+    Status = EfiRead (File, Location, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint ("Error reading file content\n");

+      goto Exit;

+    }

+

+    Status = OutputData (Location, Chunk, Width, File->BaseOffset + Offset);

+    if (EFI_ERROR(Status)) {

+      if (Status == EFI_END_OF_FILE) {

+        Status = EFI_SUCCESS;

+      }

+      goto Exit;

+    }

+  }

+

+Exit:

+  EfiClose (File);

+

+  FreePool (Location);

+

+  return EFI_SUCCESS;

+}

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdTemplate[] =

+{

+  {

+    "reset",

+    " [type]; Reset system. type = [warm] [shutdown] default is cold reset",

+    NULL,

+    EblResetCmd

+  },

+  {

+    "exit",

+    "; Exit EBL",

+    NULL,

+    EblExitCmd

+  },

+  {

+    "help",

+    " [cmd]; Help on cmd or a list of all commands if cmd is ommited",

+    NULL,

+    EblHelpCmd

+  },

+  {

+    "break",

+    "; Generate debugging breakpoint",

+    NULL,

+    EblBreakPointCmd

+  },

+  {

+    "page",

+    " [on|off]]; toggle promting on command output larger than screen",

+    NULL,

+    EblPageCmd

+  },

+  {

+    "pause",

+    " [sec]; Pause for sec[10] seconds. ",

+    NULL,

+    EblPauseCmd

+  },

+  {

+    "sleep",

+    " [sec]; Sleep for sec[10] seconds. ",

+    NULL,

+    EblSleepCmd

+  },

+  {

+    "hexdump",

+    "[.{1|2|4}] filename [Offset] [Size]; dump a file as hex .width",

+    NULL,

+    EblHexdumpCmd

+  }

+};

+

+

+EFI_HANDLE  gExternalCmdHandle = NULL;

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializeCmdTable (

+  VOID

+  )

+{

+

+  EblAddCommands (mCmdTemplate, sizeof (mCmdTemplate)/sizeof (EBL_COMMAND_TABLE));

+

+  gBS->InstallProtocolInterface (

+        &gExternalCmdHandle,

+        &gEfiEblAddCommandProtocolGuid,

+        EFI_NATIVE_INTERFACE,

+        &gEblAddCommand

+        );

+

+}

+

+

+VOID

+EblShutdownExternalCmdTable (

+  VOID

+  )

+{

+  gBS->UninstallProtocolInterface (gExternalCmdHandle, &gEfiEblAddCommandProtocolGuid,  &gEblAddCommand);

+}

+

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Dir.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Dir.c
new file mode 100644
index 0000000..c45f67b
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Dir.c
@@ -0,0 +1,353 @@
+/** @file

+  Dir for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+  Module Name:  CmdTemplate.c

+

+  Search/Replace Dir with the name of your new command

+

+**/

+

+#include "Ebl.h"

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED   CHAR8 *gFvFileType[] = {

+  "All",

+  "Bin",

+  "section",

+  "SEC",

+  "PeiCore",

+  "DxeCore",

+  "PEIM",

+  "Driver",

+  "Combo",

+  "App",

+  "NULL",

+  "FV"

+};

+

+

+/**

+  Perform a dir on a device. The device must support Simple File System Protocol

+  or the FV protocol.

+

+  Argv[0] - "dir"

+  Argv[1] - Device Name:path. Path is optional

+  Argv[2] - Optional filename to match on. A leading * means match substring

+  Argv[3] - Optional FV file type

+

+  dir fs1:\efi      ; perform a dir on fs1: device in the efi directory

+  dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but

+                      only print out files that contain the string *.efi

+  dir fv1:\         ; perform a dir on fv1: device in the efi directory

+                    NOTE: fv devices do not contain subdirs

+  dir fv1:\ * PEIM  ; will match all files of type PEIM

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblDirCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_OPEN_FILE                 *File;

+  EFI_FILE_INFO                 *DirInfo;

+  UINTN                         ReadSize;

+  UINTN                         CurrentRow;

+  CHAR16                        *MatchSubString;

+  EFI_STATUS                    GetNextFileStatus;

+  UINTN                         Key;

+  EFI_FV_FILETYPE               SearchType;

+  EFI_FV_FILETYPE               Type;

+  EFI_FV_FILE_ATTRIBUTES        Attributes;

+  UINTN                         Size;

+  EFI_GUID                      NameGuid;

+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;

+  UINT32                        AuthenticationStatus;

+  VOID                          *Section;

+  UINTN                         SectionSize;

+  EFI_FV_FILETYPE               Index;

+  UINTN                         Length;

+  UINTN                         BestMatchCount;

+  CHAR16                        UnicodeFileName[MAX_CMD_LINE];

+  CHAR8                         *Path;

+  CHAR8                         *TypeStr;

+  UINTN                         TotalSize;

+

+

+  if (Argc <= 1) {

+    Path = EfiGetCwd ();

+    if (Path == NULL) {

+      return EFI_SUCCESS;

+    }

+  } else {

+    Path = Argv[1];

+  }

+

+  File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  if (File->Type == EfiOpenFirmwareVolume) {

+    // FV Dir

+

+    SearchType = EFI_FV_FILETYPE_ALL;

+    UnicodeFileName[0] = '\0';

+    MatchSubString = &UnicodeFileName[0];

+    if (Argc > 2) {

+      AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);

+      if (UnicodeFileName[0] == '*') {

+        // Handle *Name substring matching

+        MatchSubString = &UnicodeFileName[1];

+      }

+

+      // Handle file type matchs

+      if (Argc > 3) {

+        // match a specific file type, always last argument

+        Length = AsciiStrLen (Argv[3]);

+        for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {

+          if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {

+            // exact match

+            SearchType = Index;

+            break;

+          }

+

+          if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {

+            // partial match, so keep looking to make sure there is only one partial match

+            BestMatchCount++;

+            SearchType = Index;

+          }

+        }

+

+        if (BestMatchCount > 1) {

+          SearchType = EFI_FV_FILETYPE_ALL;

+        }

+      }

+    }

+

+    TotalSize = 0;

+    Fv = File->Fv;

+    Key = 0;

+    CurrentRow = 0;

+    do {

+      Type = SearchType;

+      GetNextFileStatus = Fv->GetNextFile (

+                                Fv,

+                                &Key,

+                                &Type,

+                                &NameGuid,

+                                &Attributes,

+                                &Size

+                                );

+      if (!EFI_ERROR (GetNextFileStatus)) {

+        TotalSize += Size;

+        // Calculate size of entire file

+        Section = NULL;

+        Size = 0;

+        Status = Fv->ReadFile (

+                      Fv,

+                      &NameGuid,

+                      Section,

+                      &Size,

+                      &Type,

+                      &Attributes,

+                      &AuthenticationStatus

+                      );

+        if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {

+          // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid

+          Size = 0;

+        }

+

+        TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";

+

+        // read the UI seciton to do a name match.

+        Section = NULL;

+        Status = Fv->ReadSection (

+                        Fv,

+                        &NameGuid,

+                        EFI_SECTION_USER_INTERFACE,

+                        0,

+                        &Section,

+                        &SectionSize,

+                        &AuthenticationStatus

+                        );

+        if (!EFI_ERROR (Status)) {

+          if (StrStr (Section, MatchSubString) != NULL) {

+            AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);

+            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+              break;

+            }

+          }

+          FreePool (Section);

+        } else {

+          if (*MatchSubString == '\0') {

+            AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);

+            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+              break;

+            }

+          }

+        }

+      }

+    } while (!EFI_ERROR (GetNextFileStatus));

+

+    if (SearchType == EFI_FV_FILETYPE_ALL) {

+      AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);

+    }

+

+

+  } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {

+    // Simple File System DIR

+

+    if (File->FsFileInfo ==  NULL) {

+      return EFI_SUCCESS;

+    }

+

+    if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {

+      return EFI_SUCCESS;

+    }

+

+    // Handle *Name substring matching

+    MatchSubString = NULL;

+    UnicodeFileName[0] = '\0';

+    if (Argc > 2) {

+      AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);

+      if (UnicodeFileName[0] == '*') {

+        MatchSubString = &UnicodeFileName[1];

+      }

+    }

+

+    File->FsFileHandle->SetPosition (File->FsFileHandle, 0);

+    for (CurrentRow = 0;;) {

+      // First read gets the size

+      DirInfo = NULL;

+      ReadSize = 0;

+      Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);

+      if (Status == EFI_BUFFER_TOO_SMALL) {

+        // Allocate the buffer for the real read

+        DirInfo = AllocatePool (ReadSize);

+        if (DirInfo == NULL) {

+          goto Done;

+        }

+

+        // Read the data

+        Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);

+        if ((EFI_ERROR (Status)) || (ReadSize == 0)) {

+          break;

+        }

+      } else {

+        break;

+      }

+

+      if (MatchSubString != NULL) {

+        if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {

+          // does not match *name argument, so skip

+          continue;

+        }

+      } else if (UnicodeFileName[0] != '\0') {

+        // is not an exact match for name argument, so skip

+        if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {

+          continue;

+        }

+      }

+

+      if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {

+        AsciiPrint ("         <DIR> %s\n", &DirInfo->FileName[0]);

+      } else {

+        AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);

+      }

+

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+        break;

+      }

+

+      FreePool (DirInfo);

+    }

+

+Done:

+    if (DirInfo != NULL) {

+      FreePool (DirInfo);

+    }

+  }

+

+  EfiClose (File);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Change the Current Working Directory

+

+  Argv[0] - "cd"

+  Argv[1] - Device Name:path. Path is optional

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblCdCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  if (Argc <= 1) {

+    return EFI_SUCCESS;

+  }

+

+  return EfiSetCwd (Argv[1]);

+}

+

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =

+{

+  {

+    "dir",

+    " dirdev [*match]; directory listing of dirdev. opt match a substring",

+    NULL,

+    EblDirCmd

+  },

+  {

+    "cd",

+    " device - set the current working directory",

+    NULL,

+    EblCdCmd

+  }

+};

+

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializeDirCmd (

+  VOID

+  )

+{

+  if (FeaturePcdGet (PcdEmbeddedDirCmd)) {

+    EblAddCommands (mCmdDirTemplate, sizeof (mCmdDirTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.h b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.h
new file mode 100644
index 0000000..c2242df
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.h
@@ -0,0 +1,207 @@
+/** @file

+  Include file for basic command line parser for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+**/

+

+#ifndef __EBL_H__

+#define __EBL_H__

+

+#include <PiDxe.h>

+#include <Protocol/BlockIo.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/FirmwareVolume2.h>

+#include <Protocol/LoadFile.h>

+#include <Protocol/FirmwareVolumeBlock.h>

+#include <Protocol/PxeBaseCode.h>

+#include <Protocol/LoadedImage.h>

+#include <Protocol/EblAddCommand.h>

+#include <Protocol/PciIo.h>

+#include <Protocol/DevicePath.h>

+

+#include <Guid/FileInfo.h>

+#include <Guid/DxeServices.h>

+#include <Guid/MemoryTypeInformation.h>

+#include <Guid/MemoryAllocationHob.h>

+#include <Library/BaseLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/PrintLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Library/EfiFileLib.h>

+#include <Library/HobLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+#include <Library/EblCmdLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/UefiLib.h>

+#include <Library/EblNetworkLib.h>

+#include <Library/TimerLib.h>

+

+#include <IndustryStandard/Pci.h>

+

+//

+// Prompt for the command line

+//

+#define CMD_SEPARATOR             ';'

+#define EBL_MAX_COMMAND_COUNT     0x100

+#define MAX_CMD_HISTORY           16

+#define MAX_CMD_LINE              256

+#define MAX_ARGS                  32

+

+#define EBL_CR                    0x0a

+#define EBL_LF                    0x0d

+

+#define EFI_SET_TIMER_TO_SECOND   10000000

+

+

+

+EBL_COMMAND_TABLE *

+EblGetCommand (

+  IN CHAR8                        *CommandName

+  );

+

+

+EFI_STATUS

+EblPathToDevice (

+  IN  CHAR8                       *Path,

+  OUT EFI_HANDLE                  *DeviceHandle,

+  OUT EFI_DEVICE_PATH_PROTOCOL    **PathDevicePath,

+  OUT VOID                        **Buffer,

+  OUT UINTN                       *BufferSize

+  );

+

+BOOLEAN

+EblAnyKeyToContinueQtoQuit (

+  IN  UINTN                       *CurrentRow,

+  IN  BOOLEAN                     PrefixNewline

+  );

+

+VOID

+EblUpdateDeviceLists (

+  VOID

+  );

+

+VOID

+EblInitializeCmdTable (

+  VOID

+  );

+

+VOID

+EblShutdownExternalCmdTable (

+  VOID

+  );

+

+VOID

+EblSetTextColor (

+  UINTN                           Attribute

+  );

+

+

+EFI_STATUS

+EblGetCharKey (

+  IN OUT EFI_INPUT_KEY            *Key,

+  IN     UINTN                    TimoutInSec,

+  IN     EBL_GET_CHAR_CALL_BACK   CallBack   OPTIONAL

+  );

+

+// BugBug: Move me to a library

+INTN

+EFIAPI

+AsciiStrniCmp (

+  IN      CONST CHAR8             *FirstString,

+  IN      CONST CHAR8             *SecondString,

+  IN      UINTN                   Length

+  );

+

+

+VOID

+EblInitializeDeviceCmd (

+  VOID

+  );

+

+VOID

+EblInitializemdHwDebugCmds (

+  VOID

+  );

+

+VOID

+EblInitializeDirCmd (

+  VOID

+  );

+

+VOID

+EblInitializeHobCmd (

+  VOID

+  );

+

+VOID

+EblInitializemdHwIoDebugCmds (

+  VOID

+  );

+

+VOID

+EblInitializeScriptCmd (

+  VOID

+  );

+

+VOID

+EblInitializeNetworkCmd (

+  VOID

+  );

+

+VOID

+EblInitializeVariableCmds (

+  VOID

+  );

+

+CHAR8 *

+ParseArguments (

+  IN  CHAR8                       *CmdLine,

+  OUT UINTN                       *Argc,

+  OUT CHAR8                       **Argv

+  );

+

+EFI_STATUS

+ProcessCmdLine (

+  IN CHAR8                        *CmdLine,

+  IN UINTN                        MaxCmdLineSize

+  );

+

+EFI_STATUS

+OutputData (

+  IN UINT8                        *Address,

+  IN UINTN                        Length,

+  IN UINTN                         Width,

+  IN UINTN                        Offset

+  );

+

+UINTN

+WidthFromCommandName (

+  IN CHAR8                        *Argv,

+  IN UINTN                        Default

+  );

+

+

+extern UINTN                      gScreenColumns;

+extern UINTN                      gScreenRows;

+extern BOOLEAN                    gPageBreak;

+extern CHAR8                      *gMemMapType[];

+

+#endif

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.inf b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.inf
new file mode 100644
index 0000000..91a82d9
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Ebl.inf
@@ -0,0 +1,111 @@
+#/** @file

+# EBL Applicaiton

+#

+# This is a shell application that will display Hello World.

+# Copyright (c) 2007, Intel Corporation. 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 Section - statements that will be processed to create a Makefile.

+#

+################################################################################

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Ebl

+  FILE_GUID                      = 3CEF354A-3B7A-4519-AD70-72A134698311

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = EdkBootLoaderEntry

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+[Sources.common]

+  Main.c

+  Command.c

+  EfiDevice.c

+  HwDebug.c

+  HwIoDebug.c

+  Dir.c

+  Hob.c

+  Script.c

+  Ebl.h

+  Network.c

+  Variable.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  IntelFrameworkPkg/IntelFrameworkPkg.dec

+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  UefiLib

+  UefiApplicationEntryPoint

+  UefiBootServicesTableLib

+  UefiRuntimeServicesTableLib

+  BaseMemoryLib

+  MemoryAllocationLib

+  DevicePathLib

+  IoLib

+  PrintLib

+  PcdLib

+  EfiFileLib

+  HobLib

+  BaseLib

+  EblCmdLib

+  EblNetworkLib

+

+[LibraryClasses.ARM]

+  SemihostLib

+

+[Protocols.common]

+  gEfiFirmwareVolume2ProtocolGuid

+  gEfiFirmwareVolumeBlockProtocolGuid

+  gEfiBlockIoProtocolGuid

+  gEfiSimpleFileSystemProtocolGuid

+  gEfiLoadFileProtocolGuid

+  gEfiLoadedImageProtocolGuid

+  gEfiPxeBaseCodeProtocolGuid

+  gEfiEblAddCommandProtocolGuid

+  gEfiDiskIoProtocolGuid

+  gEfiPciIoProtocolGuid

+  gEfiSimpleNetworkProtocolGuid

+

+[Guids.common]

+  gEfiDxeServicesTableGuid

+  gEfiFileInfoGuid

+  gEfiHobMemoryAllocModuleGuid

+  gEfiMemoryTypeInformationGuid

+

+[FeaturePcd.common]

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedProbeRemovable

+

+[FixedPcd.common]

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedShellCharacterEcho

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/EfiDevice.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/EfiDevice.c
new file mode 100644
index 0000000..7d20609
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/EfiDevice.c
@@ -0,0 +1,1050 @@
+/** @file

+  EBL commands for EFI and PI Devices

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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 "Ebl.h"

+

+

+EFI_DXE_SERVICES  *gDS = NULL;

+

+

+/**

+  Print information about the File System device.

+

+  @param  File  Open File for the device

+

+**/

+VOID

+EblPrintFsInfo (

+  IN  EFI_OPEN_FILE   *File

+  )

+{

+  CHAR16 *Str;

+

+  if (File == NULL) {

+    return;

+  }

+

+  AsciiPrint ("  %a: ", File->DeviceName);

+  if (File->FsInfo != NULL) {

+    for (Str = File->FsInfo->VolumeLabel; *Str != '\0'; Str++) {

+      if (*Str == ' ') {

+        // UI makes you enter _ for space, so make the printout match that

+        *Str = '_';

+      }

+      AsciiPrint ("%c", *Str);

+    }

+    AsciiPrint (":");

+    if (File->FsInfo->ReadOnly) {

+      AsciiPrint ("ReadOnly");

+    }

+  }

+

+  AsciiPrint ("\n");

+  EfiClose (File);

+}

+

+

+/**

+  Print information about the FV devices.

+

+  @param  File  Open File for the device

+

+**/

+VOID

+EblPrintFvbInfo (

+  IN  EFI_OPEN_FILE   *File

+  )

+{

+  if (File == NULL) {

+    return;

+  }

+

+  AsciiPrint ("  %a: 0x%08lx - 0x%08lx : 0x%08x\n", File->DeviceName, File->FvStart, File->FvStart + File->FvSize - 1, File->FvSize);

+  EfiClose (File);

+}

+

+

+/**

+  Print information about the Blk IO devices.

+  If the device supports PXE dump out extra information

+

+  @param  File  Open File for the device

+

+**/

+VOID

+EblPrintBlkIoInfo (

+  IN  EFI_OPEN_FILE   *File

+  )

+{

+  UINT64                    DeviceSize;

+  UINTN                     Index;

+  UINTN                     Max;

+  EFI_OPEN_FILE             *FsFile;

+

+  if (File == NULL) {

+    return;

+  }

+

+  AsciiPrint ("  %a: ", File->DeviceName);

+

+  // print out name of file system, if any, on this block device

+  Max = EfiGetDeviceCounts (EfiOpenFileSystem);

+  if (Max != 0) {

+    for (Index = 0; Index < Max; Index++) {

+      FsFile = EfiDeviceOpenByType (EfiOpenFileSystem, Index);

+      if (FsFile != NULL) {

+        if (FsFile->EfiHandle == File->EfiHandle) {

+          AsciiPrint ("fs%d: ", Index);

+          EfiClose (FsFile);

+          break;

+        }

+        EfiClose (FsFile);

+      }

+    }

+  }

+

+  // Print out useful Block IO media properties

+  if (File->FsBlockIoMedia->RemovableMedia) {

+    AsciiPrint ("Removable ");

+  }

+  if (!File->FsBlockIoMedia->MediaPresent) {

+    AsciiPrint ("No Media\n");

+  } else {

+    if (File->FsBlockIoMedia->LogicalPartition) {

+      AsciiPrint ("Partition ");

+    }

+    DeviceSize = MultU64x32 (File->FsBlockIoMedia->LastBlock + 1, File->FsBlockIoMedia->BlockSize);

+    AsciiPrint ("Size = 0x%lX\n", DeviceSize);

+  }

+  EfiClose (File);

+}

+

+ /**

+  Print information about the Load File devices.

+  If the device supports PXE dump out extra information

+

+  @param  File  Open File for the device

+

+**/

+VOID

+EblPrintLoadFileInfo (

+  IN  EFI_OPEN_FILE   *File

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL    *DevicePathNode;

+  MAC_ADDR_DEVICE_PATH        *MacAddr;

+  UINTN                       HwAddressSize;

+  UINTN                       Index;

+

+  if (File == NULL) {

+    return;

+  }

+

+  AsciiPrint ("  %a: %a ", File->DeviceName, EblLoadFileBootTypeString (File->EfiHandle));

+

+  if (File->DevicePath != NULL) {

+    // Try to print out the MAC address

+    for (DevicePathNode = File->DevicePath;

+        !IsDevicePathEnd (DevicePathNode);

+        DevicePathNode = NextDevicePathNode (DevicePathNode)) {

+

+      if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP)) {

+        MacAddr = (MAC_ADDR_DEVICE_PATH *)DevicePathNode;

+

+        HwAddressSize = sizeof (EFI_MAC_ADDRESS);

+        if (MacAddr->IfType == 0x01 || MacAddr->IfType == 0x00) {

+          HwAddressSize = 6;

+        }

+

+        AsciiPrint ("MAC ");

+        for (Index = 0; Index < HwAddressSize; Index++) {

+          AsciiPrint ("%02x", MacAddr->MacAddress.Addr[Index] & 0xff);

+        }

+      }

+    }

+  }

+

+  AsciiPrint ("\n");

+  EfiClose (File);

+  return;

+}

+

+

+

+/**

+  Dump information about devices in the system.

+

+  fv:       PI Firmware Volume

+  fs:       EFI Simple File System

+  blk:      EFI Block IO

+  LoadFile: EFI Load File Protocol (commonly PXE network boot)

+

+  Argv[0] - "device"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblDeviceCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN         Index;

+  UINTN         CurrentRow;

+  UINTN         Max;

+

+  CurrentRow = 0;

+

+  // Need to call here to make sure Device Counts are valid

+  EblUpdateDeviceLists ();

+

+  // Now we can print out the info...

+  Max = EfiGetDeviceCounts (EfiOpenFirmwareVolume);

+  if (Max != 0) {

+    AsciiPrint ("Firmware Volume Devices:\n");

+    for (Index = 0; Index < Max; Index++) {

+      EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume, Index));

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {

+        break;

+      }

+    }

+  }

+

+  Max = EfiGetDeviceCounts (EfiOpenFileSystem);

+  if (Max != 0) {

+    AsciiPrint ("File System Devices:\n");

+    for (Index = 0; Index < Max; Index++) {

+      EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem, Index));

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {

+        break;

+      }

+    }

+  }

+

+  Max = EfiGetDeviceCounts (EfiOpenBlockIo);

+  if (Max != 0) {

+    AsciiPrint ("Block IO Devices:\n");

+    for (Index = 0; Index < Max; Index++) {

+      EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo, Index));

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {

+        break;

+      }

+    }

+  }

+

+  Max = EfiGetDeviceCounts (EfiOpenLoadFile);

+  if (Max != 0) {

+    AsciiPrint ("LoadFile Devices: (usually network)\n");

+    for (Index = 0; Index < Max; Index++) {

+      EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile, Index));

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {

+        break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Start an EFI image (PE32+ with EFI defined entry point).

+

+  Argv[0] - "start"

+  Argv[1] - device name and path

+  Argv[2] - "" string to pass into image being started

+

+  start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the

+                                      ; ascii string arg to pass to the image

+  start fv0:\FV                       ; load an FV from an FV (not common)

+  start LoadFile0:                    ; load an FV via a PXE boot

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblStartCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                  Status;

+  EFI_OPEN_FILE               *File;

+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;

+  EFI_HANDLE                  ImageHandle;

+  UINTN                       ExitDataSize;

+  CHAR16                      *ExitData;

+  VOID                        *Buffer;

+  UINTN                       BufferSize;

+  EFI_LOADED_IMAGE_PROTOCOL   *ImageInfo;

+

+  ImageHandle = NULL;

+

+  if (Argc < 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  DevicePath = File->DevicePath;

+  if (DevicePath != NULL) {

+    // check for device path form: blk, fv, fs, and loadfile

+    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);

+  } else {

+    // Check for buffer form: A0x12345678:0x1234 syntax.

+    // Means load using buffer starting at 0x12345678 of size 0x1234.

+

+    Status = EfiReadAllocatePool (File, &Buffer, &BufferSize);

+    if (EFI_ERROR (Status)) {

+      EfiClose (File);

+      return Status;

+    }

+    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);

+

+    FreePool (Buffer);

+  }

+

+  EfiClose (File);

+

+  if (!EFI_ERROR (Status)) {

+    if (Argc >= 3) {

+      // Argv[2] is a "" string that we pass directly to the EFI application without the ""

+      // We don't pass Argv[0] to the EFI Application (it's name) just the args

+      Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);

+      ASSERT_EFI_ERROR (Status);

+

+      ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]);

+      ImageInfo->LoadOptions     = AllocatePool (ImageInfo->LoadOptionsSize);

+      AsciiStrCpy (ImageInfo->LoadOptions, Argv[2]);

+    }

+

+    // Transfer control to the EFI image we loaded with LoadImage()

+    Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);

+  }

+

+  return Status;

+}

+

+

+/**

+  Load a Firmware Volume (FV) into memory from a device. This causes drivers in

+  the FV to be dispatched if the dependencies of the drivers are met.

+

+  Argv[0] - "loadfv"

+  Argv[1] - device name and path

+

+  loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk

+  loadfv fv0:\FV         ; load an FV from an FV (not common)

+  loadfv LoadFile0:      ; load an FV via a PXE boot

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblLoadFvCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                        Status;

+  EFI_OPEN_FILE                     *File;

+  VOID                              *FvStart;

+  UINTN                             FvSize;

+  EFI_HANDLE                        FvHandle;

+

+

+  if (Argc < 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (File->Type == EfiOpenMemoryBuffer) {

+    // If it is a address just use it.

+    Status = gDS->ProcessFirmwareVolume (File->Buffer, File->Size, &FvHandle);

+  } else {

+    // If it is a file read it into memory and use it

+    Status = EfiReadAllocatePool (File, &FvStart, &FvSize);

+    EfiClose (File);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);

+    if (EFI_ERROR (Status)) {

+      FreePool (FvStart);

+    }

+  }

+  return Status;

+}

+

+

+/**

+  Perform an EFI connect to connect devices that follow the EFI driver model.

+  If it is a PI system also call the dispatcher in case a new FV was made

+  available by one of the connect EFI drivers (this is not a common case).

+

+  Argv[0] - "connect"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblConnectCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS    Status;

+  UINTN         HandleCount;

+  EFI_HANDLE    *HandleBuffer;

+  UINTN         Index;

+  BOOLEAN       Dispatch;

+  EFI_OPEN_FILE *File;

+

+

+  if (Argc > 1) {

+    if ((*Argv[1] == 'd') || (*Argv[1] == 'D')) {

+      Status = gBS->LocateHandleBuffer (

+                      AllHandles,

+                      NULL,

+                      NULL,

+                      &HandleCount,

+                      &HandleBuffer

+                      );

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      for (Index = 0; Index < HandleCount; Index++) {

+        gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);

+      }

+

+      //

+      // Given we disconnect our console we should go and do a connect now

+      //

+    } else {

+      File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+      if (File != NULL) {

+        AsciiPrint ("Connecting %a\n", Argv[1]);

+        gBS->ConnectController (File->EfiHandle, NULL, NULL, TRUE);

+        EfiClose (File);

+        return EFI_SUCCESS;

+      }

+    }

+  }

+

+  Dispatch = FALSE;

+  do {

+    Status = gBS->LocateHandleBuffer (

+                    AllHandles,

+                    NULL,

+                    NULL,

+                    &HandleCount,

+                    &HandleBuffer

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    for (Index = 0; Index < HandleCount; Index++) {

+      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);

+    }

+

+    FreePool (HandleBuffer);

+

+    //

+    // Check to see if it's possible to dispatch an more DXE drivers.

+    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.

+    // If anything is Dispatched Status == EFI_SUCCESS and we will try

+    // the connect again.

+    //

+    if (gDS == NULL) {

+      Status = EFI_NOT_FOUND;

+    } else {

+      Status = gDS->Dispatch ();

+      if (!EFI_ERROR (Status)) {

+        Dispatch = TRUE;

+      }

+    }

+

+  } while (!EFI_ERROR (Status));

+

+  if (Dispatch) {

+    AsciiPrint ("Connected and dispatched\n");

+  } else {

+    AsciiPrint ("Connect\n");

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+CHAR8 *gMemMapType[] = {

+  "reserved  ",

+  "LoaderCode",

+  "LoaderData",

+  "BS_code   ",

+  "BS_data   ",

+  "RT_code   ",

+  "RT_data   ",

+  "available ",

+  "Unusable  ",

+  "ACPI_recl ",

+  "ACPI_NVS  ",

+  "MemMapIO  ",

+  "MemPortIO ",

+  "PAL_code  "

+};

+

+

+/**

+  Dump out the EFI memory map

+

+  Argv[0] - "memmap"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblMemMapCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS            Status;

+  EFI_MEMORY_DESCRIPTOR *MemMap;

+  EFI_MEMORY_DESCRIPTOR *OrigMemMap;

+  UINTN                 MemMapSize;

+  UINTN                 MapKey;

+  UINTN                 DescriptorSize;

+  UINT32                DescriptorVersion;

+  UINT64                PageCount[EfiMaxMemoryType];

+  UINTN                 Index;

+  UINT64                EntrySize;

+  UINTN                 CurrentRow;

+  UINT64                TotalMemory;

+

+  ZeroMem (PageCount, sizeof (PageCount));

+

+  AsciiPrint ("EFI Memory Map\n");

+

+  // First call is to figure out how big the buffer needs to be

+  MemMapSize = 0;

+  MemMap     = NULL;

+  Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    // In case the AllocatPool changes the memory map we added in some extra descriptors

+    MemMapSize += (DescriptorSize * 0x100);

+    OrigMemMap = MemMap = AllocatePool (MemMapSize);

+    if (OrigMemMap != NULL) {

+      // 2nd time we get the data

+      Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);

+      if (!EFI_ERROR (Status)) {

+        for (Index = 0, CurrentRow = 0; Index < MemMapSize/DescriptorSize; Index++) {

+          EntrySize = LShiftU64 (MemMap->NumberOfPages, 12);

+          AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType[MemMap->Type % EfiMaxMemoryType], MemMap->PhysicalStart, MemMap->PhysicalStart + EntrySize -1, MemMap->NumberOfPages, MemMap->Attribute);

+          if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {

+            break;

+          }

+

+          PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;

+          MemMap = NEXT_MEMORY_DESCRIPTOR (MemMap, DescriptorSize);

+        }

+      }

+

+      for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++) {

+        if (PageCount[Index] != 0) {

+          AsciiPrint ("\n  %a %,7ld Pages (%,14ld)", gMemMapType[Index], PageCount[Index], LShiftU64 (PageCount[Index], 12));

+          if (Index == EfiLoaderCode ||

+              Index == EfiLoaderData ||

+              Index == EfiBootServicesCode ||

+              Index == EfiBootServicesData ||

+              Index == EfiRuntimeServicesCode ||

+              Index == EfiRuntimeServicesData ||

+              Index == EfiConventionalMemory ||

+              Index == EfiACPIReclaimMemory ||

+              Index == EfiACPIMemoryNVS ||

+              Index == EfiPalCode

+          ) {

+            // Count total memory

+            TotalMemory += PageCount[Index];

+          }

+        }

+      }

+

+      AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory, 8), LShiftU64 (TotalMemory, 12));

+

+      FreePool (OrigMemMap);

+

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+

+

+/**

+  Load a file into memory and optionally jump to it. A load address can be

+  specified or automatically allocated. A quoted command line can optionally

+  be passed into the image.

+

+  Argv[0] - "go"

+  Argv[1] - Device Name:path for the file to load

+  Argv[2] - Address to load to or '*' if the load address will be allocated

+  Argv[3] - Optional Entry point to the image. Image will be called if present

+  Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs

+            to include the command name

+

+  go fv1:\EblCmdX  0x10000  0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX

+    from FV1 to location 0x10000 and call the entry point at 0x10010 passing

+    in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

+

+  go fv0:\EblCmdX  *  0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0

+    to location allocated by this command and call the entry point at offset 0x10

+    passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

+

+  go fv1:\EblCmdX  0x10000; Load EblCmdX to address 0x10000 and return

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblGoCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_OPEN_FILE                 *File;

+  VOID                          *Address;

+  UINTN                         Size;

+  EBL_COMMMAND                  EntryPoint;

+  UINTN                         EntryPointArgc;

+  CHAR8                         *EntryPointArgv[MAX_ARGS];

+

+

+  if (Argc <= 2) {

+    // device name and laod address are required

+    return EFI_SUCCESS;

+  }

+

+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    AsciiPrint ("  %a is not a valid path\n", Argv[1]);

+    return EFI_SUCCESS;

+  }

+

+  EntryPoint  = (EBL_COMMMAND)((Argc > 3) ? (UINTN)AsciiStrHexToUintn (Argv[3]) : (UINTN)NULL);

+  if (Argv[2][0] == '*') {

+    // * Means allocate the buffer

+    Status = EfiReadAllocatePool (File, &Address, &Size);

+

+    // EntryPoint is relative to the start of the image

+    EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);

+

+  } else {

+    Address = (VOID *)AsciiStrHexToUintn (Argv[2]);

+    Size = File->Size;

+

+    // File->Size for LoadFile is lazy so we need to use the tell to figure it out

+    EfiTell (File, NULL);

+    Status = EfiRead (File, Address, &Size);

+  }

+

+  if (!EFI_ERROR (Status)) {

+    AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size, Address);

+

+    if (Argc > 3) {

+      if (Argc > 4) {

+        ParseArguments (Argv[4], &EntryPointArgc, EntryPointArgv);

+      } else {

+        EntryPointArgc = 1;

+        EntryPointArgv[0] = File->FileName;

+      }

+

+      Status = EntryPoint (EntryPointArgc, EntryPointArgv);

+    }

+  }

+

+  EfiClose (File);

+  return Status;

+}

+

+#define FILE_COPY_CHUNK 0x20000

+

+EFI_STATUS

+EblFileCopyCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_OPEN_FILE *Source      = NULL;

+  EFI_OPEN_FILE *Destination = NULL;

+  EFI_STATUS    Status       = EFI_SUCCESS;

+  VOID          *Buffer      = NULL;

+  UINTN         Size;

+  UINTN         Offset;

+  UINTN         Chunk        = FILE_COPY_CHUNK;

+  UINTN         FileNameLen;

+  CHAR8*        DestFileName;

+  CHAR8*        SrcFileName;

+  CHAR8*        SrcPtr;

+

+  if (Argc < 3) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  DestFileName = Argv[2];

+  FileNameLen = AsciiStrLen (DestFileName);

+

+  // Check if the destination file name looks like a directory

+  if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) {

+    // Set the pointer after the source drive (eg: after fs1:)

+    SrcPtr = AsciiStrStr (Argv[1], ":");

+    if (SrcPtr == NULL) {

+      SrcPtr = Argv[1];

+    } else {

+      SrcPtr++;

+      if (*SrcPtr == '\\') {

+        SrcPtr++;

+      }

+    }

+

+    if (*SrcPtr == '\0') {

+      AsciiPrint("Source file incorrect.\n");

+    }

+

+    // Skip the Source Directories

+    while (1) {

+      SrcFileName = SrcPtr;

+      SrcPtr = AsciiStrStr (SrcPtr,"\\");

+      if (SrcPtr != NULL) {

+        SrcPtr++;

+      } else {

+        break;

+      }

+    }

+

+    if (*SrcFileName == '\0') {

+      AsciiPrint("Source file incorrect (Error 2).\n");

+    }

+

+    // Construct the destination filepath

+    DestFileName = (CHAR8*)AllocatePool (FileNameLen + AsciiStrLen (SrcFileName) + 1);

+    AsciiStrCpy (DestFileName, Argv[2]);

+    AsciiStrCat (DestFileName, SrcFileName);

+  }

+

+  Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);

+  if (Source == NULL) {

+    AsciiPrint("Source file open error.\n");

+    return EFI_NOT_FOUND;

+  }

+

+  Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);

+  if (Destination == NULL) {

+    AsciiPrint("Destination file open error.\n");

+    return EFI_NOT_FOUND;

+  }

+

+  Buffer = AllocatePool(FILE_COPY_CHUNK);

+  if (Buffer == NULL) {

+    goto Exit;

+  }

+

+  Size = EfiTell(Source, NULL);

+

+  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {

+    Chunk = FILE_COPY_CHUNK;

+

+    Status = EfiRead(Source, Buffer, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Read file error %r\n", Status);

+      goto Exit;

+    }

+

+    Status = EfiWrite(Destination, Buffer, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Write file error %r\n", Status);

+      goto Exit;

+    }

+  }

+

+  // Any left over?

+  if (Offset < Size) {

+    Chunk = Size - Offset;

+

+    Status = EfiRead(Source, Buffer, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Read file error %r\n", Status);

+      goto Exit;

+    }

+

+    Status = EfiWrite(Destination, Buffer, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Write file error %r\n", Status);

+      goto Exit;

+    }

+  }

+

+

+Exit:

+  if (Source != NULL) {

+    Status = EfiClose(Source);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Source close error %r\n", Status);

+    }

+  }

+  if (Destination != NULL) {

+    Status = EfiClose(Destination);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("Destination close error %r\n", Status);

+    }

+

+    // Case when we have concated the filename to the destination directory

+    if (DestFileName != Argv[2]) {

+      FreePool (DestFileName);

+    }

+  }

+

+  if (Buffer != NULL) {

+    FreePool(Buffer);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+EblFileDiffCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_OPEN_FILE *File1   = NULL;

+  EFI_OPEN_FILE *File2   = NULL;

+  EFI_STATUS    Status   = EFI_SUCCESS;

+  VOID          *Buffer1 = NULL;

+  VOID          *Buffer2 = NULL;

+  UINTN         Size1;

+  UINTN         Size2;

+  UINTN         Offset;

+  UINTN         Chunk   = FILE_COPY_CHUNK;

+

+  if (Argc != 3) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  File1 = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File1 == NULL) {

+    AsciiPrint("File 1 open error.\n");

+    return EFI_NOT_FOUND;

+  }

+

+  File2 = EfiOpen(Argv[2], EFI_FILE_MODE_READ, 0);

+  if (File2 == NULL) {

+    AsciiPrint("File 2 open error.\n");

+    return EFI_NOT_FOUND;

+  }

+

+  Size1 = EfiTell(File1, NULL);

+  Size2 = EfiTell(File2, NULL);

+

+  if (Size1 != Size2) {

+    AsciiPrint("Files differ.\n");

+    goto Exit;

+  }

+

+  Buffer1 = AllocatePool(FILE_COPY_CHUNK);

+  if (Buffer1 == NULL) {

+    goto Exit;

+  }

+

+  Buffer2 = AllocatePool(FILE_COPY_CHUNK);

+  if (Buffer2 == NULL) {

+    goto Exit;

+  }

+

+  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size1; Offset += Chunk) {

+    Chunk = FILE_COPY_CHUNK;

+

+    Status = EfiRead(File1, Buffer1, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 1 read error\n");

+      goto Exit;

+    }

+

+    Status = EfiRead(File2, Buffer2, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 2 read error\n");

+      goto Exit;

+    }

+

+    if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {

+      AsciiPrint("Files differ.\n");

+      goto Exit;

+    };

+  }

+

+  // Any left over?

+  if (Offset < Size1) {

+    Chunk = Size1 - Offset;

+

+    Status = EfiRead(File1, Buffer1, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 1 read error\n");

+      goto Exit;

+    }

+

+    Status = EfiRead(File2, Buffer2, &Chunk);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 2 read error\n");

+      goto Exit;

+    }

+  }

+

+  if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {

+    AsciiPrint("Files differ.\n");

+  } else {

+    AsciiPrint("Files are identical.\n");

+  }

+

+Exit:

+  if (File1 != NULL) {

+    Status = EfiClose(File1);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 1 close error %r\n", Status);

+    }

+  }

+

+  if (File2 != NULL) {

+    Status = EfiClose(File2);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("File 2 close error %r\n", Status);

+    }

+  }

+

+  if (Buffer1 != NULL) {

+    FreePool(Buffer1);

+  }

+

+  if (Buffer2 != NULL) {

+    FreePool(Buffer2);

+  }

+

+  return Status;

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] =

+{

+  {

+    "connect",

+    "[d]; Connect all EFI devices. d means disconnect",

+    NULL,

+    EblConnectCmd

+  },

+  {

+    "device",

+    "; Show information about boot devices",

+    NULL,

+    EblDeviceCmd

+  },

+  {

+    "go",

+    " dev:path loadaddress entrypoint args; load to given address and jump in",

+    NULL,

+    EblGoCmd

+  },

+  {

+    "loadfv",

+    " devname; Load PI FV from device",

+    NULL,

+    EblLoadFvCmd

+  },

+  {

+    "start",

+    " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",

+    NULL,

+    EblStartCmd

+  },

+  {

+    "memmap",

+    "; dump EFI memory map",

+    NULL,

+    EblMemMapCmd

+  },

+  {

+    "cp",

+    " file1 file2; copy file only.",

+    NULL,

+    EblFileCopyCmd

+  },

+  {

+    "diff",

+    " file1 file2; compare files",

+    NULL,

+    EblFileDiffCmd

+  }

+};

+

+

+/**

+  Initialize the commands in this in this file

+**/

+

+VOID

+EblInitializeDeviceCmd (

+  VOID

+  )

+{

+  EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);

+  EblAddCommands (mCmdDeviceTemplate, sizeof (mCmdDeviceTemplate)/sizeof (EBL_COMMAND_TABLE));

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Hob.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Hob.c
new file mode 100644
index 0000000..8b7a52e
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Hob.c
@@ -0,0 +1,232 @@
+/** @file

+  Hob command for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+  Module Name:  Hob.c

+

+  Search/Replace Dir with the name of your new command

+

+  Boot Mode:

+  ==========

+  BOOT_WITH_FULL_CONFIGURATION                  0x00

+  BOOT_WITH_MINIMAL_CONFIGURATION               0x01

+  BOOT_ASSUMING_NO_CONFIGURATION_CHANGES        0x02

+  BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03

+  BOOT_WITH_DEFAULT_SETTINGS                    0x04

+  BOOT_ON_S4_RESUME                             0x05

+  BOOT_ON_S5_RESUME                             0x06

+  BOOT_ON_S2_RESUME                             0x10

+  BOOT_ON_S3_RESUME                             0x11

+  BOOT_ON_FLASH_UPDATE                          0x12

+  BOOT_IN_RECOVERY_MODE                         0x20

+  BOOT_IN_RECOVERY_MODE_MASK                    0x40

+  BOOT_SPECIAL_MASK                             0x80

+

+  Mem Alloc HOB Type:

+  ===================

+  typedef enum {

+    EfiReservedMemoryType       = 0x00

+    EfiLoaderCode               = 0x01

+    EfiLoaderData               = 0x02

+    EfiBootServicesCode         = 0x03

+    EfiBootServicesData         = 0x04

+    EfiRuntimeServicesCode      = 0x05

+    EfiRuntimeServicesData      = 0x06

+    EfiConventionalMemory       = 0x07

+    EfiUnusableMemory           = 0x08

+    EfiACPIReclaimMemory        = 0x09

+    EfiACPIMemoryNVS            = 0x0a

+    EfiMemoryMappedIO           = 0x0b

+    EfiMemoryMappedIOPortSpace  = 0x0c

+    EfiPalCode                  = 0x0d

+    EfiMaxMemoryType            = 0x0e

+  } EFI_MEMORY_TYPE;

+

+  Resource Hob Tye:

+  =================

+  EFI_RESOURCE_SYSTEM_MEMORY          0

+  EFI_RESOURCE_MEMORY_MAPPED_IO       1

+  EFI_RESOURCE_IO                     2

+  EFI_RESOURCE_FIRMWARE_DEVICE        3

+  EFI_RESOURCE_MEMORY_MAPPED_IO_PORT  4

+  EFI_RESOURCE_MEMORY_RESERVED        5

+  EFI_RESOURCE_IO_RESERVED            6

+  EFI_RESOURCE_MAX_MEMORY_TYPE        7

+

+  Resource Hob Attribute (last thing printed):

+  ============================================

+  EFI_RESOURCE_ATTRIBUTE_PRESENT                  0x00000001

+  EFI_RESOURCE_ATTRIBUTE_INITIALIZED              0x00000002

+  EFI_RESOURCE_ATTRIBUTE_TESTED                   0x00000004

+  EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC           0x00000008

+  EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC         0x00000010

+  EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1           0x00000020

+  EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2           0x00000040

+  EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED           0x00000080

+  EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED          0x00000100

+  EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED      0x00000200

+  EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE              0x00000400

+  EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE        0x00000800

+  EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE  0x00001000

+  EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE     0x00002000

+  EFI_RESOURCE_ATTRIBUTE_16_BIT_IO                0x00004000

+  EFI_RESOURCE_ATTRIBUTE_32_BIT_IO                0x00008000

+  EFI_RESOURCE_ATTRIBUTE_64_BIT_IO                0x00010000

+  EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED        0x00020000

+

+**/

+

+#include "Ebl.h"

+// BugBug: Autogen does not allow this to be included currently

+//#include <EdkModulePkg/Include/EdkDxe.h>

+

+GLOBAL_REMOVE_IF_UNREFERENCED char *mHobResourceType[] = {

+  "Memory     ",

+  "MMIO       ",

+  "IO         ",

+  "Firmware   ",

+  "MMIO Port  ",

+  "Reserved   ",

+  "IO Reserved",

+  "Illegal    "

+};

+

+

+/**

+  Dump out the HOBs in the system. HOBs are defined in the PI specification

+  and they are used to hand off information from PEI to DXE.

+

+  Argv[0] - "hob"

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblHobCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN                         CurrentRow;

+  EFI_PEI_HOB_POINTERS          Hob;

+  EFI_MEMORY_TYPE_INFORMATION   *EfiMemoryTypeInformation;

+  UINTN                         Index;

+

+  CurrentRow = 0;

+  for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {

+    if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {

+      AsciiPrint ("PHIT HOB Ver %x Boot Mode %02x Top %lx  Bottom %lx\n",

+        Hob.HandoffInformationTable->Version,

+        Hob.HandoffInformationTable->BootMode,

+        Hob.HandoffInformationTable->EfiMemoryTop,

+        Hob.HandoffInformationTable->EfiMemoryBottom

+        );

+

+      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+        return EFI_SUCCESS;

+      }

+

+      AsciiPrint ("    Free Top %lx Free Bottom %lx  End Of HOB %lx\n",

+        Hob.HandoffInformationTable->EfiFreeMemoryTop,

+        Hob.HandoffInformationTable->EfiFreeMemoryBottom,

+        Hob.HandoffInformationTable->EfiEndOfHobList

+        );

+

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {

+      // mod(%) on array index is just to prevent buffer overrun

+      AsciiPrint ("Mem Alloc HOB %a %g %08lx:%lx\n",

+        (Hob.MemoryAllocation->AllocDescriptor.MemoryType < EfiMaxMemoryType) ? gMemMapType[Hob.MemoryAllocation->AllocDescriptor.MemoryType] : "ILLEGAL TYPE",

+        &Hob.MemoryAllocation->AllocDescriptor.Name,

+        Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,

+        Hob.MemoryAllocation->AllocDescriptor.MemoryLength

+        );

+      if (CompareGuid (&gEfiHobMemoryAllocModuleGuid, &Hob.MemoryAllocation->AllocDescriptor.Name)) {

+        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+          return EFI_SUCCESS;

+        }

+        AsciiPrint ("    Module Name %g EntryPoint %lx\n", &Hob.MemoryAllocationModule->ModuleName, Hob.MemoryAllocationModule->EntryPoint);

+      }

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

+      AsciiPrint ("Resource HOB %a %g %08lx:%lx\n    Attributes: %08x\n",

+        (Hob.ResourceDescriptor->ResourceType < EFI_RESOURCE_MAX_MEMORY_TYPE) ? mHobResourceType[Hob.ResourceDescriptor->ResourceType] : mHobResourceType[EFI_RESOURCE_MAX_MEMORY_TYPE],

+        &Hob.ResourceDescriptor->Owner,

+        Hob.ResourceDescriptor->PhysicalStart,

+        Hob.ResourceDescriptor->ResourceLength,

+        Hob.ResourceDescriptor->ResourceAttribute

+        );

+        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+          return EFI_SUCCESS;

+        }

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {

+      AsciiPrint ("GUID HOB %g\n", &Hob.Guid->Name);

+      if (CompareGuid (&gEfiMemoryTypeInformationGuid, &Hob.Guid->Name)) {

+        EfiMemoryTypeInformation = GET_GUID_HOB_DATA (Hob.Guid);

+        for (Index = 0; Index < (GET_GUID_HOB_DATA_SIZE (Hob.Guid)/sizeof (EFI_MEMORY_TYPE_INFORMATION)); Index++, EfiMemoryTypeInformation++) {

+          if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+            return EFI_SUCCESS;

+          }

+          AsciiPrint ("    %a 0x%08x\n",

+            (EfiMemoryTypeInformation->Type < EfiMaxMemoryType) ? gMemMapType[EfiMemoryTypeInformation->Type] : "END       ",

+            EfiMemoryTypeInformation->NumberOfPages

+            );

+       }

+      }

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_FV) {

+      AsciiPrint ("FV HOB %08lx:%08lx\n", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->Length);

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_CPU) {

+      AsciiPrint ("CPU HOB: Mem %x IO %x\n", Hob.Cpu->SizeOfMemorySpace, Hob.Cpu->SizeOfIoSpace);

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_POOL) {

+      AsciiPrint ("Mem Pool HOB:\n");

+/* Not in PI

+    } else if (Hob.Header->HobType == EFI_HOB_TYPE_CV) {

+      AsciiPrint ("CV HOB: %08lx:%08lx\n", Hob.CapsuleVolume->BaseAddress, Hob.CapsuleVolume->Length);

+ */

+    }

+

+    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {

+      break;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHobTemplate[] =

+{

+  {

+    "hob",

+    "; dump HOBs",

+    NULL,

+    EblHobCmd

+  }

+};

+

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializeHobCmd (

+  VOID

+  )

+{

+  if (FeaturePcdGet (PcdEmbeddedHobCmd)) {

+    EblAddCommands (mCmdHobTemplate, sizeof (mCmdHobTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwDebug.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwDebug.c
new file mode 100644
index 0000000..226b245
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwDebug.c
@@ -0,0 +1,342 @@
+/** @file

+  Basic command line parser for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+  Module Name:  HwDebug.c

+

+  Commands useful for debugging hardware.

+

+**/

+

+#include "Ebl.h"

+

+

+/**

+  Dump memory

+

+  Argv[0] - "md"[.#] # is optional width 1, 2, 4, or 8. Default 1

+  Argv[1] - Hex Address to dump

+  Argv[2] - Number of hex bytes to dump (0x20 is default)

+

+  md.4 0x123445678 50 ; Dump 0x50 4 byte quantities starting at 0x123445678

+  md   0x123445678 40 ; Dump 0x40 1 byte quantities starting at 0x123445678

+  md   0x123445678    ; Dump 0x20 1 byte quantities starting at 0x123445678

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblMdCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  STATIC UINT8  *Address = NULL;

+  STATIC UINTN  Length   = 0x20;

+  STATIC UINTN  Width;

+

+  Width = WidthFromCommandName (Argv[0], 1);

+

+  switch (Argc) {

+    case 3:

+      Length = AsciiStrHexToUintn(Argv[2]);

+    case 2:

+      Address = (UINT8 *)AsciiStrHexToUintn (Argv[1]);

+    default:

+      break;

+  }

+

+  OutputData (Address, Length, Width, (UINTN)Address);

+

+  Address += Length;

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Fill Memory with data

+

+  Argv[0] - "mfill"[.#] # is optional width 1, 2, 4, or 8. Default 4

+  Argv[1] - Hex Address to fill

+  Argv[2] - Data to write (0x00 is default)

+  Argv[3] - Number of units to dump.

+

+  mf.1 0x123445678 aa 100 ; Start at 0x123445678 and write aa (1 byte) to the next 100 bytes

+  mf.4 0x123445678 aa 100 ; Start at 0x123445678 and write aa (4 byte) to the next 400 bytes

+  mf 0x123445678 aa       ; Start at 0x123445678 and write aa (4 byte) to the next 1 byte

+  mf 0x123445678          ; Start at 0x123445678 and write 00 (4 byte) to the next 1 byte

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblMfillCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN   Address;

+  UINTN   EndAddress;

+  UINT32  Data;

+  UINTN   Length;

+  UINTN   Width;

+

+  if (Argc < 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Width = WidthFromCommandName (Argv[0], 4);

+

+  Address = AsciiStrHexToUintn (Argv[1]);

+  Data    = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 0;

+  Length  = (Argc > 3) ? AsciiStrHexToUintn (Argv[3]) : 1;

+

+  for (EndAddress = Address + (Length * Width); Address < EndAddress; Address += Width) {

+    if (Width == 4) {

+      MmioWrite32 (Address, Data);

+    } else if (Width == 2) {

+      MmioWrite16 (Address, (UINT16)Data);

+    } else {

+      MmioWrite8 (Address, (UINT8)Data);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+//

+// Strings for PCI Class code [2]

+//

+CHAR8 *gPciDevClass[] = {

+  "Old Device             ",

+  "Mass storage           ",

+  "Network                ",

+  "Display                ",

+  "Multimedia             ",

+  "Memory controller      ",

+  "Bridge device          ",

+  "simple communications  ",

+  "base system peripherals",

+  "Input devices          ",

+  "Docking stations       ",

+  "Processors             ",

+  "serial bus             ",

+};

+

+

+CHAR8 *gPciSerialClassCodes[] = {

+  "Mass storage           ",

+  "Firewire               ",

+  "ACCESS bus             ",

+  "SSA                    ",

+  "USB                     "

+};

+

+

+/**

+  PCI Dump

+

+  Argv[0] - "pci"

+  Argv[1] - bus

+  Argv[2] - dev

+  Argv[3] - func

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblPciCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_PCI_IO_PROTOCOL           *Pci;

+  UINTN                         HandleCount;

+  EFI_HANDLE                    *HandleBuffer;

+  UINTN                         Seg;

+  UINTN                         Bus;

+  UINTN                         Dev;

+  UINTN                         Func;

+  UINTN                         BusArg;

+  UINTN                         DevArg;

+  UINTN                         FuncArg;

+  UINTN                         Index;

+  UINTN                         Count;

+  PCI_TYPE_GENERIC              PciHeader;

+  PCI_TYPE_GENERIC              *Header;

+  PCI_BRIDGE_CONTROL_REGISTER   *Bridge;

+  PCI_DEVICE_HEADER_TYPE_REGION *Device;

+  PCI_DEVICE_INDEPENDENT_REGION *Hdr;

+  CHAR8                         *Str;

+  UINTN                         ThisBus;

+

+

+  BusArg  = (Argc > 1) ? AsciiStrDecimalToUintn (Argv[1]) : 0;

+  DevArg  = (Argc > 2) ? AsciiStrDecimalToUintn (Argv[2]) : 0;

+  FuncArg = (Argc > 3) ? AsciiStrDecimalToUintn (Argv[3]) : 0;

+

+  Header = &PciHeader;

+

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);

+  if (EFI_ERROR (Status)) {

+    AsciiPrint ("No PCI devices found in the system\n");

+    return EFI_SUCCESS;

+  }

+

+  if (Argc == 1) {

+    // Dump all PCI devices

+    AsciiPrint ("BusDevFun  VendorId DeviceId  Device Class          Sub-Class\n");

+    AsciiPrint ("_____________________________________________________________");

+    for (ThisBus = 0; ThisBus <= PCI_MAX_BUS; ThisBus++) {

+      for (Index = 0; Index < HandleCount; Index++) {

+        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);

+        if (!EFI_ERROR (Status)) {

+          Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);

+          if (ThisBus != Bus) {

+            continue;

+          }

+          AsciiPrint ("\n%03d.%02d.%02d", Bus, Dev, Func);

+          Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), &PciHeader);

+          if (!EFI_ERROR (Status)) {

+            Hdr = &PciHeader.Bridge.Hdr;

+

+            if (Hdr->ClassCode[2] < sizeof (gPciDevClass)/sizeof (VOID *)) {

+              Str = gPciDevClass[Hdr->ClassCode[2]];

+              if (Hdr->ClassCode[2] == PCI_CLASS_SERIAL) {

+                if (Hdr->ClassCode[1] < sizeof (gPciSerialClassCodes)/sizeof (VOID *)) {

+                  // print out Firewire or USB inplace of Serial Bus controllers

+                  Str = gPciSerialClassCodes[Hdr->ClassCode[1]];

+                }

+              }

+            } else {

+              Str = "Unknown device         ";

+            }

+            AsciiPrint ("  0x%04x   0x%04x    %a 0x%02x", Hdr->VendorId, Hdr->DeviceId, Str, Hdr->ClassCode[1]);

+          }

+          if (Seg != 0) {

+            // Only print Segment if it is non zero. If you only have one PCI segment it is

+            // redundent to print it out

+            AsciiPrint (" Seg:%d", Seg);

+          }

+        }

+      }

+    }

+    AsciiPrint ("\n");

+  } else {

+    // Dump specific PCI device

+    for (Index = 0; Index < HandleCount; Index++) {

+      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);

+      if (!EFI_ERROR (Status)) {

+        Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);

+        if ((Bus == BusArg) && (Dev == DevArg) && (Func == FuncArg)) {

+          // Only print Segment if it is non zero. If you only have one PCI segment it is

+          // redundant to print it out

+          if (Seg != 0) {

+            AsciiPrint ("Seg:%d ", Seg);

+          }

+          AsciiPrint ("Bus:%d Dev:%d Func:%d ", Bus, Dev, Func);

+

+          Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0, sizeof (PciHeader)/sizeof (UINT32), Header);

+          if (!EFI_ERROR (Status)) {

+            Hdr = &PciHeader.Bridge.Hdr;

+            if (IS_PCI_BRIDGE (&PciHeader.Bridge)) {

+              Bridge = &PciHeader.Bridge.Bridge;

+              AsciiPrint (

+                "PCI Bridge. Bus Primary %d Secondary %d Subordinate %d\n",

+                Bridge->PrimaryBus, Bridge->SecondaryBus, Bridge->SubordinateBus

+                );

+              AsciiPrint ("  Bar 0: 0x%08x  Bar 1: 0x%08x\n", Bridge->Bar[0], Bridge->Bar[1]);

+            } else {

+              Device = &PciHeader.Device.Device;

+              AsciiPrint (

+                "VendorId: 0x%04x DeviceId: 0x%04x SubSusVendorId: 0x%04x SubSysDeviceId: 0x%04x\n",

+                Hdr->VendorId, Hdr->DeviceId, Device->SubsystemVendorID, Device->SubsystemID

+                );

+              AsciiPrint ("  Class Code: 0x%02x 0x%02x 0x%02x\n", Hdr->ClassCode[2], Hdr->ClassCode[1], Hdr->ClassCode[0]);

+              for (Count = 0; Count < 6; Count++) {

+                AsciiPrint ("  Bar %d: 0x%08x\n", Count, Device->Bar[Count]);

+              }

+            }

+          }

+

+          AsciiPrint ("\n");

+          break;

+        }

+      }

+    }

+  }

+

+  FreePool (HandleBuffer);

+  return EFI_SUCCESS;

+}

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdPciDebugTemplate[] = {

+  {

+    "pci",

+    " [bus] [dev] [func]; Dump PCI",

+    NULL,

+    EblPciCmd

+  }

+};

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwDebugTemplate[] =

+{

+  {

+    "md",

+    "[.{1|2|4}] [Addr] [Len] [1|2|4]; Memory Dump from Addr Len bytes",

+    NULL,

+    EblMdCmd

+  },

+  {

+    "mfill",

+    "[.{1|2|4}] Addr Len [data]; Memory Fill Addr Len*(1|2|4) bytes of data(0)",

+    NULL,

+    EblMfillCmd

+  },

+};

+

+

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializemdHwDebugCmds (

+  VOID

+  )

+{

+  if (FeaturePcdGet (PcdEmbeddedHwDebugCmd)) {

+    EblAddCommands (mCmdHwDebugTemplate, sizeof (mCmdHwDebugTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+  if (FeaturePcdGet (PcdEmbeddedPciDebugCmd)) {

+    EblAddCommands (mCmdPciDebugTemplate, sizeof (mCmdPciDebugTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwIoDebug.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwIoDebug.c
new file mode 100644
index 0000000..c9144fe
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/HwIoDebug.c
@@ -0,0 +1,151 @@
+/** @file

+  Hardware IO based debug commands

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+  Commands useful for debugging hardware. IO commands separated out as not all

+  processor architectures support the IO command.

+

+**/

+

+#include "Ebl.h"

+

+

+

+/**

+  Read from IO space

+

+  Argv[0] - "ioread"[.#] # is optional width 1, 2, or 4. Default 1

+  Argv[1] - Hex IO address

+

+  ior.4 0x3f8  ;Do a 32-bit IO Read from 0x3f8

+  ior   0x3f8  ;Do a  8-bit IO Read from 0x3f8

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblIoReadCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN   Width;

+  UINTN   Port;

+  UINTN   Data;

+

+  if (Argc < 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Port = AsciiStrHexToUintn (Argv[1]);

+  Width = WidthFromCommandName (Argv[0], 1);

+

+  if (Width == 1) {

+    Data = IoRead8 (Port);

+  } else if (Width == 2) {

+    Data = IoRead16 (Port);

+  } else if (Width == 4) {

+    Data = IoRead32 (Port);

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  AsciiPrint ("0x%04x = 0x%x", Port, Data);

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Write to IO space

+

+  Argv[0] - "iowrite"[.#] # is optional width 1, 2, or 4. Default 1

+  Argv[1] - Hex IO address

+  Argv[2] - Hex data to write

+

+  iow.4 0x3f8 af  ;Do a 32-bit IO write of af to 0x3f8

+  iow   0x3f8 af  ;Do an 8-bit IO write of af to 0x3f8

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblIoWriteCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  UINTN   Width;

+  UINTN   Port;

+  UINTN   Data;

+

+  if (Argc < 3) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Port = AsciiStrHexToUintn (Argv[1]);

+  Data = AsciiStrHexToUintn (Argv[2]);

+  Width = WidthFromCommandName (Argv[0], 1);

+

+  if (Width == 1) {

+    IoWrite8 (Port, (UINT8)Data);

+  } else if (Width == 2) {

+    IoWrite16 (Port, (UINT16)Data);

+  } else if (Width == 4) {

+    IoWrite32 (Port, (UINT32)Data);

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+  return EFI_SUCCESS;

+}

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdHwIoDebugTemplate[] =

+{

+  {

+    "ioread",

+    "[.{1|2|4}] Port ; IO read of width byte(s) from Port",

+    NULL,

+    EblIoReadCmd

+  },

+  {

+    "iowrite",

+    "[.{1|2|4}] Port Data ; IO write Data of width byte(s) to Port",

+    NULL,

+    EblIoWriteCmd

+  }

+};

+

+

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializemdHwIoDebugCmds (

+  VOID

+  )

+{

+  if (FeaturePcdGet (PcdEmbeddedIoEnable)) {

+    EblAddCommands (mCmdHwIoDebugTemplate, sizeof (mCmdHwIoDebugTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Main.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Main.c
new file mode 100644
index 0000000..dc17d26
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Main.c
@@ -0,0 +1,674 @@
+/** @file

+  Basic command line parser for EBL (Embedded Boot Loader)

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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 "Ebl.h"

+

+// Globals for command history processing

+INTN mCmdHistoryEnd     = -1;

+INTN mCmdHistoryStart   = -1;

+INTN mCmdHistoryCurrent = -1;

+CHAR8 mCmdHistory[MAX_CMD_HISTORY][MAX_CMD_LINE];

+CHAR8 *mCmdBlank = "";

+

+// Globals to remember current screen geometry

+UINTN gScreenColumns;

+UINTN gScreenRows;

+

+// Global to turn on/off breaking commands with prompts before they scroll the screen

+BOOLEAN gPageBreak = TRUE;

+

+VOID

+RingBufferIncrement (

+  IN  INTN  *Value

+  )

+{

+  *Value = *Value + 1;

+

+  if (*Value >= MAX_CMD_HISTORY) {

+    *Value = 0;

+  }

+}

+

+VOID

+RingBufferDecrement (

+  IN  INTN  *Value

+  )

+{

+  *Value = *Value - 1;

+

+  if (*Value < 0) {

+    *Value = MAX_CMD_HISTORY - 1;

+  }

+}

+

+/**

+  Save this command in the circular history buffer. Older commands are

+  overwritten with newer commands.

+

+  @param  Cmd   Command line to archive the history of.

+

+  @return None

+

+**/

+VOID

+SetCmdHistory (

+  IN  CHAR8 *Cmd

+  )

+{

+  // Don't bother adding empty commands to the list

+  if (AsciiStrLen(Cmd) != 0) {

+

+    // First entry

+    if (mCmdHistoryStart == -1) {

+      mCmdHistoryStart   = 0;

+      mCmdHistoryEnd     = 0;

+    } else {

+      // Record the new command at the next index

+      RingBufferIncrement(&mCmdHistoryStart);

+

+      // If the next index runs into the end index, shuffle end back by one

+      if (mCmdHistoryStart == mCmdHistoryEnd) {

+        RingBufferIncrement(&mCmdHistoryEnd);

+      }

+    }

+

+    // Copy the new command line into the ring buffer

+    AsciiStrnCpy(&mCmdHistory[mCmdHistoryStart][0], Cmd, MAX_CMD_LINE);

+  }

+

+  // Reset the command history for the next up arrow press

+  mCmdHistoryCurrent = mCmdHistoryStart;

+}

+

+

+/**

+  Retreave data from the Command History buffer. Direction maps into up arrow

+  an down arrow on the command line

+

+  @param  Direction  Command forward or back

+

+  @return The Command history based on the Direction

+

+**/

+CHAR8 *

+GetCmdHistory (

+  IN UINT16   Direction

+  )

+{

+  CHAR8 *HistoricalCommand = NULL;

+

+  // No history yet?

+  if (mCmdHistoryCurrent == -1) {

+    HistoricalCommand = mCmdBlank;

+    goto Exit;

+  }

+

+  if (Direction == SCAN_UP) {

+    HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];

+

+    // if we just echoed the last command, hang out there, don't wrap around

+    if (mCmdHistoryCurrent == mCmdHistoryEnd) {

+      goto Exit;

+    }

+

+    // otherwise, back up by one

+    RingBufferDecrement(&mCmdHistoryCurrent);

+

+  } else if (Direction == SCAN_DOWN) {

+

+    // if we last echoed the start command, put a blank prompt out

+    if (mCmdHistoryCurrent == mCmdHistoryStart) {

+      HistoricalCommand = mCmdBlank;

+      goto Exit;

+    }

+

+    // otherwise increment the current pointer and return that command

+    RingBufferIncrement(&mCmdHistoryCurrent);

+    RingBufferIncrement(&mCmdHistoryCurrent);

+

+    HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];

+    RingBufferDecrement(&mCmdHistoryCurrent);

+  }

+

+Exit:

+  return HistoricalCommand;

+}

+

+

+/**

+  Parse the CmdLine and break it up into Argc (arg count) and Argv (array of

+  pointers to each argument). The Cmd buffer is altered and separators are

+  converted to string terminators. This allows Argv to point into CmdLine.

+  A CmdLine can support multiple commands. The next command in the command line

+  is returned if it exists.

+

+  @param  CmdLine String to parse for a set of commands

+  @param  Argc    Returns the number of arguments in the CmdLine current command

+  @param  Argv    Argc pointers to each string in CmdLine

+

+  @return Next Command in the command line or NULL if non exists

+**/

+CHAR8 *

+ParseArguments (

+  IN  CHAR8  *CmdLine,

+  OUT UINTN  *Argc,

+  OUT CHAR8  **Argv

+  )

+{

+  UINTN   Arg;

+  CHAR8   *Char;

+  BOOLEAN LookingForArg;

+  BOOLEAN InQuote;

+

+  *Argc = 0;

+  if (AsciiStrLen (CmdLine) == 0) {

+    return NULL;

+  }

+

+  // Walk a single command line. A CMD_SEPARATOR allows multiple commands on a single line

+  InQuote       = FALSE;

+  LookingForArg = TRUE;

+  for (Char = CmdLine, Arg = 0; *Char != '\0'; Char++) {

+    if (!InQuote && *Char == CMD_SEPARATOR) {

+      break;

+    }

+

+    // Perform any text conversion here

+    if (*Char == '\t') {

+      // TAB to space

+      *Char = ' ';

+    }

+

+    if (LookingForArg) {

+      // Look for the beginning of an Argv[] entry

+      if (*Char == '"') {

+        Argv[Arg++] = ++Char;

+        LookingForArg = FALSE;

+        InQuote = TRUE;

+      } else if (*Char != ' ') {

+        Argv[Arg++] = Char;

+        LookingForArg = FALSE;

+      }

+    } else {

+      // Looking for the terminator of an Argv[] entry

+      if (!InQuote && (*Char == ' ')) {

+        *Char = '\0';

+        LookingForArg = TRUE;

+      } else if (!InQuote && (*Char == '"') && (*(Char-1) != '\\')) {

+        InQuote = TRUE;

+      } else if (InQuote && (*Char == '"') && (*(Char-1) != '\\')) {

+        *Char = '\0';

+        InQuote = FALSE;

+      }

+    }

+  }

+

+  *Argc = Arg;

+

+  if (*Char == CMD_SEPARATOR) {

+    // Replace the command delimiter with null and return pointer to next command line

+    *Char = '\0';

+    return ++Char;

+  }

+

+  return NULL;

+}

+

+

+/**

+  Return a keypress or optionally timeout if a timeout value was passed in.

+  An optional callback function is called every second when waiting for a

+  timeout.

+

+  @param  Key           EFI Key information returned

+  @param  TimeoutInSec  Number of seconds to wait to timeout

+  @param  CallBack      Callback called every second during the timeout wait

+

+  @return EFI_SUCCESS  Key was returned

+  @return EFI_TIMEOUT  If the TimoutInSec expired

+

+**/

+EFI_STATUS

+EblGetCharKey (

+  IN OUT EFI_INPUT_KEY            *Key,

+  IN     UINTN                    TimeoutInSec,

+  IN     EBL_GET_CHAR_CALL_BACK   CallBack   OPTIONAL

+  )

+{

+  EFI_STATUS    Status;

+  UINTN         WaitCount;

+  UINTN         WaitIndex;

+  EFI_EVENT     WaitList[2];

+

+  WaitCount   = 1;

+  WaitList[0] = gST->ConIn->WaitForKey;

+  if (TimeoutInSec != 0) {

+    // Create a time event for 1 sec duration if we have a timeout

+    gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &WaitList[1]);

+    gBS->SetTimer (WaitList[1], TimerPeriodic, EFI_SET_TIMER_TO_SECOND);

+    WaitCount++;

+  }

+

+  for (;;) {

+    Status = gBS->WaitForEvent (WaitCount, WaitList, &WaitIndex);

+    ASSERT_EFI_ERROR (Status);

+

+    switch (WaitIndex) {

+    case 0:

+      // Key event signaled

+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);

+      if (!EFI_ERROR (Status)) {

+        if (WaitCount == 2) {

+          gBS->CloseEvent (WaitList[1]);

+        }

+        return EFI_SUCCESS;

+      }

+      break;

+

+    case 1:

+      // Periodic 1 sec timer signaled

+      TimeoutInSec--;

+      if (CallBack != NULL) {

+        // Call the users callback function if registered

+        CallBack (TimeoutInSec);

+      }

+      if (TimeoutInSec == 0) {

+        gBS->CloseEvent (WaitList[1]);

+        return EFI_TIMEOUT;

+      }

+      break;

+    default:

+      ASSERT (FALSE);

+    }

+  }

+}

+

+

+/**

+  This routine is used prevent command output data from scrolling off the end

+  of the screen. The global gPageBreak is used to turn on or off this feature.

+  If the CurrentRow is near the end of the screen pause and print out a prompt

+  If the use hits Q to quit return TRUE else for any other key return FALSE.

+  PrefixNewline is used to figure out if a newline is needed before the prompt

+  string. This depends on the last print done before calling this function.

+  CurrentRow is updated by one on a call or set back to zero if a prompt is

+  needed.

+

+  @param  CurrentRow  Used to figure out if its the end of the page and updated

+  @param  PrefixNewline  Did previous print issue a newline

+

+  @return TRUE if Q was hit to quit, FALSE in all other cases.

+

+**/

+BOOLEAN

+EblAnyKeyToContinueQtoQuit (

+  IN  UINTN   *CurrentRow,

+  IN  BOOLEAN PrefixNewline

+  )

+{

+  EFI_INPUT_KEY     InputKey;

+

+  if (!gPageBreak) {

+    // global disable for this feature

+    return FALSE;

+  }

+

+  if (*CurrentRow >= (gScreenRows - 2)) {

+    if (PrefixNewline) {

+      AsciiPrint ("\n");

+    }

+    AsciiPrint ("Any key to continue (Q to quit): ");

+    EblGetCharKey (&InputKey, 0, NULL);

+    AsciiPrint ("\n");

+

+    // Time to promt to stop the screen. We have to leave space for the prompt string

+    *CurrentRow = 0;

+    if (InputKey.UnicodeChar == 'Q' || InputKey.UnicodeChar == 'q') {

+      return TRUE;

+    }

+  } else {

+    *CurrentRow += 1;

+  }

+

+  return FALSE;

+}

+

+

+/**

+  Set the text color of the EFI Console. If a zero is passed in reset to

+  default text/background color.

+

+  @param  Attribute   For text and background color

+

+**/

+VOID

+EblSetTextColor (

+  UINTN   Attribute

+  )

+{

+  if (Attribute == 0) {

+    // Set the text color back to default

+    Attribute = (UINTN)PcdGet32 (PcdEmbeddedDefaultTextColor);

+  }

+

+  gST->ConOut->SetAttribute (gST->ConOut, Attribute);

+}

+

+

+/**

+  Collect the keyboard input for a cmd line. Carriage Return, New Line, or ESC

+  terminates the command line. You can edit the command line via left arrow,

+  delete and backspace and they all back up and erase the command line.

+  No edit of command line is possible without deletion at this time!

+  The up arrow and down arrow fill Cmd with information from the history

+  buffer.

+

+  @param  Cmd         Command line to return

+  @param  CmdMaxSize  Maximum size of Cmd

+

+  @return The Status of EblGetCharKey()

+

+**/

+EFI_STATUS

+GetCmd (

+  IN OUT  CHAR8   *Cmd,

+  IN      UINTN   CmdMaxSize

+  )

+{

+  EFI_STATUS    Status;

+  UINTN         Index;

+  UINTN         Index2;

+  CHAR8         Char;

+  CHAR8         *History;

+  EFI_INPUT_KEY Key;

+

+  for (Index = 0; Index < CmdMaxSize - 1;) {

+    Status = EblGetCharKey (&Key, 0, NULL);

+    if (EFI_ERROR (Status)) {

+      Cmd[Index] = '\0';

+      AsciiPrint ("\n");

+      return Status;

+    }

+

+    Char = (CHAR8)Key.UnicodeChar;

+    if ((Char == '\n') || (Char == '\r') || (Char == 0x7f)) {

+      Cmd[Index] = '\0';

+      if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {

+        AsciiPrint ("\n\r");

+      }

+      return EFI_SUCCESS;

+    } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){

+      if (Index != 0) {

+        Index--;

+        //

+        // Update the display

+        //

+        AsciiPrint ("\b \b");

+      }

+    } else if ((Key.ScanCode == SCAN_UP) || Key.ScanCode == SCAN_DOWN) {

+      History = GetCmdHistory (Key.ScanCode);

+      //

+      // Clear display line

+      //

+      for (Index2 = 0; Index2 < Index; Index2++) {

+        AsciiPrint ("\b \b");

+      }

+      AsciiPrint (History);

+      Index = AsciiStrLen (History);

+      AsciiStrnCpy (Cmd, History, CmdMaxSize);

+    } else {

+      Cmd[Index++] = Char;

+      if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {

+        AsciiPrint ("%c", Char);

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Print the boot up banner for the EBL.

+**/

+VOID

+EblPrintStartupBanner (

+  VOID

+  )

+{

+  AsciiPrint ("Embedded Boot Loader (");

+  EblSetTextColor (EFI_YELLOW);

+  AsciiPrint ("EBL");

+  EblSetTextColor (0);

+  AsciiPrint (") prototype. Built at %a on %a\n",__TIME__, __DATE__);

+  AsciiPrint ("THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN 'AS IS' BASIS,\nWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\n");

+  AsciiPrint ("Please send feedback to edk2-devel@lists.sourceforge.net\n");

+}

+

+

+/**

+  Send null requests to all removable media block IO devices so the a media add/remove/change

+  can be detected in real before we execute a command.

+

+  This is mainly due to the fact that the FAT driver does not do this today so you can get stale

+  dir commands after an SD Card has been removed.

+**/

+VOID

+EblProbeRemovableMedia (

+  VOID

+  )

+{

+  UINTN         Index;

+  UINTN         Max;

+  EFI_OPEN_FILE *File;

+

+  //

+  // Probe for media insertion/removal in removable media devices

+  //

+  Max = EfiGetDeviceCounts (EfiOpenBlockIo);

+  if (Max != 0) {

+    for (Index = 0; Index < Max; Index++) {

+      File = EfiDeviceOpenByType (EfiOpenBlockIo, Index);

+      if (File != NULL) {

+        if (File->FsBlockIoMedia->RemovableMedia) {

+          // Probe to see if media is present (or not) or media changed

+          //  this causes the ReinstallProtocolInterface() to fire in the

+          //  block io driver to update the system about media change events

+          File->FsBlockIo->ReadBlocks (File->FsBlockIo, File->FsBlockIo->Media->MediaId, (EFI_LBA)0, 0, NULL);

+        }

+        EfiClose (File);

+      }

+    }

+  }

+}

+

+

+

+

+/**

+  Print the prompt for the EBL.

+**/

+VOID

+EblPrompt (

+  VOID

+  )

+{

+  EblSetTextColor (EFI_YELLOW);

+  AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());

+  EblSetTextColor (0);

+  AsciiPrint ("%a", ">");

+}

+

+

+

+/**

+  Parse a command line and execute the commands. The ; separator allows

+  multiple commands for each command line. Stop processing if one of the

+  commands returns an error.

+

+  @param  CmdLine          Command Line to process.

+  @param  MaxCmdLineSize   MaxSize of the Command line

+

+  @return EFI status of the Command

+

+**/

+EFI_STATUS

+ProcessCmdLine (

+  IN CHAR8      *CmdLine,

+  IN UINTN      MaxCmdLineSize

+  )

+{

+  EFI_STATUS          Status;

+  EBL_COMMAND_TABLE   *Cmd;

+  CHAR8               *Ptr;

+  UINTN               Argc;

+  CHAR8               *Argv[MAX_ARGS];

+

+  // Parse the command line. The loop processes commands separated by ;

+  for (Ptr = CmdLine, Status = EFI_SUCCESS; Ptr != NULL;) {

+    Ptr = ParseArguments (Ptr, &Argc, Argv);

+    if (Argc != 0) {

+      Cmd = EblGetCommand (Argv[0]);

+      if (Cmd != NULL) {

+        // Execute the Command!

+        Status = Cmd->Command (Argc, Argv);

+        if (Status == EFI_ABORTED) {

+          // exit command so lets exit

+          break;

+        } else if (Status == EFI_TIMEOUT) {

+          // pause command got input so don't process any more cmd on this cmd line

+          break;

+        } else if (EFI_ERROR (Status)) {

+          AsciiPrint ("%a returned %r error\n", Cmd->Name, Status);

+          // if any command fails stop processing CmdLine

+          break;

+        }

+      } else {

+        AsciiPrint ("The command '%a' is not supported.\n", Argv[0]);

+      }

+    }

+  }

+

+  return Status;

+}

+

+

+

+/**

+  Embedded Boot Loader (EBL) - A simple EFI command line application for embedded

+  devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that

+  gets executed automatically. The ; separator allows multiple commands

+  for each command line.

+

+  @param  ImageHandle   EFI ImageHandle for this application.

+  @param  SystemTable   EFI system table

+

+  @return EFI status of the application

+

+**/

+EFI_STATUS

+EFIAPI

+EdkBootLoaderEntry (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  CHAR8       CmdLine[MAX_CMD_LINE];

+  CHAR16      *CommandLineVariable = NULL;

+  CHAR16      *CommandLineVariableName = L"default-cmdline";

+  UINTN       CommandLineVariableSize = 0;

+  EFI_GUID    VendorGuid;

+

+  // Initialize tables of commands

+  EblInitializeCmdTable ();

+  EblInitializeDeviceCmd ();

+  EblInitializemdHwDebugCmds ();

+  EblInitializemdHwIoDebugCmds ();

+  EblInitializeDirCmd ();

+  EblInitializeHobCmd ();

+  EblInitializeScriptCmd ();

+  EblInitializeExternalCmd ();

+  EblInitializeNetworkCmd();

+  EblInitializeVariableCmds ();

+

+  if (gST->ConOut == NULL) {

+    DEBUG((EFI_D_ERROR,"Error: No Console Output\n"));

+    return EFI_NOT_READY;

+  }

+

+  // Disable the 5 minute EFI watchdog time so we don't get automatically reset

+  gBS->SetWatchdogTimer (0, 0, 0, NULL);

+

+  if (FeaturePcdGet (PcdEmbeddedMacBoot)) {

+    // A MAC will boot in graphics mode, so turn it back to text here

+    // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.

+    // DisableQuietBoot ();

+

+    // Enable the biggest output screen size possible

+    gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);

+

+  }

+

+  // Save current screen mode

+  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows);

+

+  EblPrintStartupBanner ();

+

+  // Parse command line and handle commands separated by ;

+  // The loop prints the prompt gets user input and saves history

+

+  // Look for a variable with a default command line, otherwise use the Pcd

+  ZeroMem(&VendorGuid, sizeof(EFI_GUID));

+

+  Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    CommandLineVariable = AllocatePool(CommandLineVariableSize);

+

+    Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);

+    if (!EFI_ERROR(Status)) {

+      UnicodeStrToAsciiStr(CommandLineVariable, CmdLine);

+    }

+

+    FreePool(CommandLineVariable);

+  }

+

+  if (EFI_ERROR(Status)) {

+    AsciiStrCpy (CmdLine, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand));

+  }

+

+  for (;;) {

+    Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE);

+    if (Status == EFI_ABORTED) {

+      // if a command returns EFI_ABORTED then exit the EBL

+      EblShutdownExternalCmdTable ();

+      return EFI_SUCCESS;

+    }

+

+    // get the command line from the user

+    EblPrompt ();

+    GetCmd (CmdLine, MAX_CMD_LINE);

+    SetCmdHistory (CmdLine);

+

+    if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) {

+      // Probe removable media devices to see if media has been inserted or removed.

+      EblProbeRemovableMedia ();

+    }

+  }

+}

+

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Network.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Network.c
new file mode 100644
index 0000000..c0055d5
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Network.c
@@ -0,0 +1,104 @@
+/** @file

+  EBL commands for Network Devices

+

+  Copyright (c) 2008 - 2009, Apple Inc. 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 "Ebl.h"

+

+EFI_STATUS

+ParseIp (

+  IN  CHAR8           *String,

+  OUT EFI_IP_ADDRESS  *Address

+  )

+{

+  Address->v4.Addr[0] = (UINT8)AsciiStrDecimalToUintn (String);

+  String = AsciiStrStr(String, ".") + 1;

+  Address->v4.Addr[1] = (UINT8)AsciiStrDecimalToUintn (String);

+  String = AsciiStrStr(String, ".") + 1;

+  Address->v4.Addr[2] = (UINT8)AsciiStrDecimalToUintn (String);

+  String = AsciiStrStr(String, ".") + 1;

+  Address->v4.Addr[3] = (UINT8)AsciiStrDecimalToUintn (String);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EblIpCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS        Status = EFI_INVALID_PARAMETER;

+  EFI_MAC_ADDRESS   Mac;

+  EFI_IP_ADDRESS    Ip;

+

+  if (Argc == 1) {

+    // Get current IP/MAC

+

+    // Get current MAC address

+    Status = EblGetCurrentMacAddress (&Mac);

+    if (EFI_ERROR (Status)) {

+      goto Exit;

+    }

+

+    AsciiPrint ("MAC Address:  %02x:%02x:%02x:%02x:%02x:%02x\n", Mac.Addr[0],  Mac.Addr[1],  Mac.Addr[2],  Mac.Addr[3],  Mac.Addr[4],  Mac.Addr[5]);

+

+    // Get current IP address

+    Status = EblGetCurrentIpAddress (&Ip);

+    if (EFI_ERROR(Status)) {

+      AsciiPrint("IP Address is not configured.\n");

+      Status = EFI_SUCCESS;

+      goto Exit;

+    }

+

+    AsciiPrint("IP Address:   %d.%d.%d.%d\n", Ip.v4.Addr[0], Ip.v4.Addr[1],Ip.v4.Addr[2], Ip.v4.Addr[3]);

+

+  } else if ((Argv[1][0] == 'r') && (Argc == 2)) {

+    // Get new address via dhcp

+    Status = EblPerformDHCP (TRUE);

+  } else if ((Argv[1][0] == 's') && (Argc == 3)) {

+    // Set static IP

+    Status = ParseIp (Argv[2], &Ip);

+    if (EFI_ERROR (Status)) {

+      goto Exit;

+    }

+

+    Status = EblSetStationIp (&Ip, NULL);

+  }

+

+Exit:

+  return Status;

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdNetworkTemplate[] =

+{

+  {

+    "ip",

+    " ; print current ip address\n\r   [r]; request DHCP address\n\r   [s] ipaddr; set static IP address",

+    NULL,

+    EblIpCmd

+  }

+};

+

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializeNetworkCmd (

+  VOID

+  )

+{

+  EblAddCommands (mCmdNetworkTemplate, sizeof (mCmdNetworkTemplate)/sizeof (EBL_COMMAND_TABLE));

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Script.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Script.c
new file mode 100644
index 0000000..a739e37
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Script.c
@@ -0,0 +1,126 @@
+/** @file

+  Script command allows the execution of commands from a text file

+

+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2009, Apple Inc. 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.

+

+  Module Name:  EfiDevice.c

+

+**/

+

+#include "Ebl.h"

+

+

+/**

+  Execute the passed in file like a series of commands. The ; can be used on

+  a single line to indicate multiple commands per line. The Ascii text file

+  can contain any number of lines. The following line termination forms are

+  supported:

+    LF   : Unix, Mac OS X*, BeOS

+    CR+LF: MS-DOS*, Microsoft Windows*

+    CR   : Commodore, Apple II, and really Mac OS

+    LF+CR: for simplicity and completeness

+

+  Argv[0] - "script"

+  Argv[1] - Device Name:path for the file to load

+

+  script fv1:\script.txt

+

+  @param  Argc   Number of command arguments in Argv

+  @param  Argv   Array of strings that represent the parsed command line.

+                 Argv[0] is the command name

+

+  @return EFI_SUCCESS

+

+**/

+EFI_STATUS

+EblScriptCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_OPEN_FILE                 *File;

+  VOID                          *Address;

+  UINTN                         Size;

+  CHAR8                         *Ptr;

+  CHAR8                         *ScanPtr;

+  UINTN                         CmdLineSize;

+

+

+

+  if (Argc < 2) {

+    // file name required

+    return EFI_SUCCESS;

+  }

+

+  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);

+  if (File == NULL) {

+    AsciiPrint ("  %a is not a valid path\n", Argv[1]);

+    return EFI_SUCCESS;

+  }

+

+  Status = EfiReadAllocatePool (File, &Address, &Size);

+  if (!EFI_ERROR (Status)) {

+    // Loop through each line in the text file

+    for (Ptr = (CHAR8 *)Address; (Ptr < (((CHAR8 *)Address) + Size)) && !EFI_ERROR (Status); Ptr += CmdLineSize) {

+      for (CmdLineSize = 0, ScanPtr = Ptr; ; CmdLineSize++, ScanPtr++) {

+        // look for the end of the line

+        if ((*ScanPtr == EBL_CR) || (*ScanPtr == EBL_LF)) {

+          // convert to NULL as this is what input routine would do

+          *ScanPtr = 0;

+          if ((*(ScanPtr + 1) == EBL_CR) || (*(ScanPtr + 1) == EBL_LF)) {

+            // if its a set get the 2nd EOL char

+            CmdLineSize++;

+            *(ScanPtr + 1) = 0;

+          }

+          CmdLineSize++;

+          break;

+        }

+

+      }

+

+      Status = ProcessCmdLine (Ptr, CmdLineSize);

+    }

+

+    FreePool (Address);

+  }

+

+  EfiClose (File);

+  return Status;

+}

+

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mScriptTemplate[] = {

+  {

+    "script",

+    " device:path; load an ascii file and execute it like commands",

+    NULL,

+    EblScriptCmd

+  }

+};

+

+

+/**

+  Initialize the commands in this in this file

+**/

+

+VOID

+EblInitializeScriptCmd (

+  VOID

+  )

+{

+  if (FeaturePcdGet (PcdEmbeddedScriptCmd)) {

+    EblAddCommands (mScriptTemplate, sizeof (mScriptTemplate)/sizeof (EBL_COMMAND_TABLE));

+  }

+}

+

diff --git a/uefi/linaro-edk2/EmbeddedPkg/Ebl/Variable.c b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Variable.c
new file mode 100644
index 0000000..f7627a8
--- /dev/null
+++ b/uefi/linaro-edk2/EmbeddedPkg/Ebl/Variable.c
@@ -0,0 +1,213 @@
+/** @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 "Ebl.h"

+

+#include <Guid/GlobalVariable.h>

+

+EFI_STATUS

+EblGetCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS        Status = EFI_INVALID_PARAMETER;

+  UINTN       Size;

+  VOID*       Value;

+  CHAR8*      AsciiVariableName = NULL;

+  CHAR16*     VariableName;

+  UINT32      Index;

+

+  if (Argc == 1) {

+    AsciiPrint("Variable name is missing.\n");

+    return Status;

+  }

+

+  for (Index = 1; Index < Argc; Index++) {

+    if (Argv[Index][0] == '-') {

+      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);

+    } else {

+      AsciiVariableName = Argv[Index];

+    }

+  }

+

+  if (AsciiVariableName == NULL) {

+    AsciiPrint("Variable name is missing.\n");

+    return Status;

+  } else {

+    VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));

+    AsciiStrToUnicodeStr (AsciiVariableName,VariableName);

+  }

+

+  // Try to get the variable size.

+  Value = NULL;

+  Size = 0;

+  Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);

+  if (Status == EFI_NOT_FOUND) {

+    AsciiPrint("Variable name '%s' not found.\n",VariableName);

+  } 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)) {

+      AsciiPrint("Error: '%r'\n",Status);

+    } else {

+      AsciiPrint("%a=%a\n",AsciiVariableName,Value);

+    }

+    FreePool(Value);

+  } else {

+    AsciiPrint("Error: '%r'\n",Status);

+  }

+

+  FreePool(VariableName);

+  return Status;

+}

+

+EFI_STATUS

+EblSetCmd (

+  IN UINTN  Argc,

+  IN CHAR8  **Argv

+  )

+{

+  EFI_STATUS    Status = EFI_INVALID_PARAMETER;

+  CHAR8*        AsciiVariableSetting = NULL;

+  CHAR8*        AsciiVariableName;

+  CHAR8*        AsciiValue;

+  UINT32        AsciiValueLength;

+  CHAR16*       VariableName;

+  UINT32        Index;

+  UINT32        EscapedQuotes = 0;

+  BOOLEAN       Volatile = FALSE;

+

+  if (Argc == 1) {

+    AsciiPrint("Variable name is missing.\n");

+    return Status;

+  }

+

+  for (Index = 1; Index < Argc; Index++) {

+    if (AsciiStrCmp(Argv[Index],"-v") == 0) {

+      Volatile = 0;

+    } else if (Argv[Index][0] == '-') {

+      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);

+    } else {

+      AsciiVariableSetting = Argv[Index];

+    }

+  }

+

+  if (AsciiVariableSetting == NULL) {

+    AsciiPrint("Variable name is missing.\n");

+    return Status;

+  }

+

+  // Check if it is a valid variable setting

+  AsciiValue = AsciiStrStr (AsciiVariableSetting,"=");

+  if (AsciiValue == NULL) {

+    //

+    // There is no value. It means this variable will be deleted

+    //

+

+    // Convert VariableName into Unicode

+    VariableName = AllocatePool((AsciiStrLen (AsciiVariableSetting) + 1) * sizeof (CHAR16));

+    AsciiStrToUnicodeStr (AsciiVariableSetting,VariableName);

+

+    Status = gRT->SetVariable (

+                          VariableName,

+                          &gEfiGlobalVariableGuid,

+                          ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |

+                          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                          0,

+                          NULL

+                          );

+    if (!EFI_ERROR(Status)) {

+      AsciiPrint("Variable '%s' deleted\n",VariableName);

+    } else {

+      AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n");

+    }

+    return Status;

+  }

+

+  AsciiValue[0] = '\0';

+  AsciiVariableName = AsciiVariableSetting;

+  AsciiValue++;

+

+  // Clean AsciiValue from quote

+  if (AsciiValue[0] == '"') {

+    AsciiValue++;

+  }

+  AsciiValueLength = AsciiStrLen (AsciiValue);

+  if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) {

+    AsciiValue[AsciiValueLength-1] = '\0';

+  }

+

+  // Clean AsciiValue from escaped quotes

+  for (Index = 0; Index < AsciiValueLength; Index++) {

+    if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) {

+      EscapedQuotes++;

+    }

+    AsciiValue[Index-EscapedQuotes] = AsciiValue[Index];

+  }

+  // Fill the end of the value with '\0'

+  for (Index = 0; Index < EscapedQuotes; Index++) {

+    AsciiValue[AsciiValueLength-1-Index] = '\0';

+  }

+

+  // Convert VariableName into Unicode

+  VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));

+  AsciiStrToUnicodeStr (AsciiVariableName,VariableName);

+

+  Status = gRT->SetVariable (

+                      VariableName,

+                      &gEfiGlobalVariableGuid,

+                      ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |

+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                      AsciiStrLen (AsciiValue)+1,

+                      AsciiValue

+                      );

+  if (!EFI_ERROR(Status)) {

+    AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue);

+  }

+

+  return Status;

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdVariableTemplate[] =

+{

+  {

+    "get",

+    " ; get UEFI variable\n\r   [v]; verbose",

+    NULL,

+    EblGetCmd

+  },

+  {

+    "set",

+    " ; set UEFI variable\n\r   [v]; create volatile variable",

+    NULL,

+    EblSetCmd

+  }

+};

+

+/**

+  Initialize the commands in this in this file

+**/

+VOID

+EblInitializeVariableCmds (

+  VOID

+  )

+{

+  EblAddCommands (mCmdVariableTemplate, sizeof (mCmdVariableTemplate)/sizeof (EBL_COMMAND_TABLE));

+}