]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Ebl/Main.c
ARM Packages: Removed trailing spaces
[mirror_edk2.git] / EmbeddedPkg / Ebl / Main.c
index d3dcc58a929f0744bea195dbdad6175e2028b5d3..dc17d26c712e1ed888cc5d76c26825a3f201bf00 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
   Basic command line parser for EBL (Embedded Boot Loader)\r
 \r
-  Copyright (c) 2007, Intel Corporation<BR>\r
-  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
 \r
-  All rights reserved. This program and the accompanying materials\r
+  This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
   http://opensource.org/licenses/bsd-license.php\r
@@ -31,13 +31,13 @@ UINTN gScreenRows;
 // Global to turn on/off breaking commands with prompts before they scroll the screen\r
 BOOLEAN gPageBreak = TRUE;\r
 \r
-VOID \r
+VOID\r
 RingBufferIncrement (\r
   IN  INTN  *Value\r
   )\r
 {\r
   *Value = *Value + 1;\r
-  \r
+\r
   if (*Value >= MAX_CMD_HISTORY) {\r
     *Value = 0;\r
   }\r
@@ -49,14 +49,14 @@ RingBufferDecrement (
   )\r
 {\r
   *Value = *Value - 1;\r
-  \r
+\r
   if (*Value < 0) {\r
     *Value = MAX_CMD_HISTORY - 1;\r
   }\r
 }\r
 \r
 /**\r
-  Save this command in the circular history buffer. Older commands are \r
+  Save this command in the circular history buffer. Older commands are\r
   overwritten with newer commands.\r
 \r
   @param  Cmd   Command line to archive the history of.\r
@@ -71,7 +71,7 @@ SetCmdHistory (
 {\r
   // Don't bother adding empty commands to the list\r
   if (AsciiStrLen(Cmd) != 0) {\r
-  \r
+\r
     // First entry\r
     if (mCmdHistoryStart == -1) {\r
       mCmdHistoryStart   = 0;\r
@@ -79,19 +79,19 @@ SetCmdHistory (
     } else {\r
       // Record the new command at the next index\r
       RingBufferIncrement(&mCmdHistoryStart);\r
-  \r
+\r
       // If the next index runs into the end index, shuffle end back by one\r
       if (mCmdHistoryStart == mCmdHistoryEnd) {\r
         RingBufferIncrement(&mCmdHistoryEnd);\r
       }\r
     }\r
-  \r
+\r
     // Copy the new command line into the ring buffer\r
     AsciiStrnCpy(&mCmdHistory[mCmdHistoryStart][0], Cmd, MAX_CMD_LINE);\r
   }\r
-  \r
+\r
   // Reset the command history for the next up arrow press\r
-  mCmdHistoryCurrent = mCmdHistoryStart;  \r
+  mCmdHistoryCurrent = mCmdHistoryStart;\r
 }\r
 \r
 \r
@@ -110,48 +110,48 @@ GetCmdHistory (
   )\r
 {\r
   CHAR8 *HistoricalCommand = NULL;\r
-  \r
+\r
   // No history yet?\r
   if (mCmdHistoryCurrent == -1) {\r
     HistoricalCommand = mCmdBlank;\r
     goto Exit;\r
   }\r
-  \r
+\r
   if (Direction == SCAN_UP) {\r
     HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];\r
-    \r
+\r
     // if we just echoed the last command, hang out there, don't wrap around\r
     if (mCmdHistoryCurrent == mCmdHistoryEnd) {\r
       goto Exit;\r
     }\r
-    \r
+\r
     // otherwise, back up by one\r
     RingBufferDecrement(&mCmdHistoryCurrent);\r
-    \r
+\r
   } else if (Direction == SCAN_DOWN) {\r
-    \r
+\r
     // if we last echoed the start command, put a blank prompt out\r
     if (mCmdHistoryCurrent == mCmdHistoryStart) {\r
       HistoricalCommand = mCmdBlank;\r
       goto Exit;\r
     }\r
-    \r
+\r
     // otherwise increment the current pointer and return that command\r
     RingBufferIncrement(&mCmdHistoryCurrent);\r
     RingBufferIncrement(&mCmdHistoryCurrent);\r
-    \r
+\r
     HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];\r
     RingBufferDecrement(&mCmdHistoryCurrent);\r
   }\r
 \r
-Exit:  \r
+Exit:\r
   return HistoricalCommand;\r
 }\r
 \r
 \r
 /**\r
   Parse the CmdLine and break it up into Argc (arg count) and Argv (array of\r
-  pointers to each argument). The Cmd buffer is altered and seperators are \r
+  pointers to each argument). The Cmd buffer is altered and separators are\r
   converted to string terminators. This allows Argv to point into CmdLine.\r
   A CmdLine can support multiple commands. The next command in the command line\r
   is returned if it exists.\r
@@ -179,22 +179,22 @@ ParseArguments (
     return NULL;\r
   }\r
 \r
-  // Walk a single command line. A CMD_SEPERATOR allows mult commands on a single line\r
+  // Walk a single command line. A CMD_SEPARATOR allows multiple commands on a single line\r
   InQuote       = FALSE;\r
   LookingForArg = TRUE;\r
   for (Char = CmdLine, Arg = 0; *Char != '\0'; Char++) {\r
-    if (!InQuote && *Char == CMD_SEPERATOR) {\r
+    if (!InQuote && *Char == CMD_SEPARATOR) {\r
       break;\r
     }\r
 \r
-    // Perform any text coversion here\r
+    // Perform any text conversion here\r
     if (*Char == '\t') {\r
       // TAB to space\r
       *Char = ' ';\r
     }\r
 \r
     if (LookingForArg) {\r
-      // Look for the beging of an Argv[] entry\r
+      // Look for the beginning of an Argv[] entry\r
       if (*Char == '"') {\r
         Argv[Arg++] = ++Char;\r
         LookingForArg = FALSE;\r
@@ -202,20 +202,25 @@ ParseArguments (
       } else if (*Char != ' ') {\r
         Argv[Arg++] = Char;\r
         LookingForArg = FALSE;\r
-      } \r
+      }\r
     } else {\r
       // Looking for the terminator of an Argv[] entry\r
-      if ((InQuote && (*Char == '"')) || (!InQuote && (*Char == ' '))) {\r
+      if (!InQuote && (*Char == ' ')) {\r
         *Char = '\0';\r
         LookingForArg = TRUE;\r
+      } else if (!InQuote && (*Char == '"') && (*(Char-1) != '\\')) {\r
+        InQuote = TRUE;\r
+      } else if (InQuote && (*Char == '"') && (*(Char-1) != '\\')) {\r
+        *Char = '\0';\r
+        InQuote = FALSE;\r
       }\r
-    }    \r
+    }\r
   }\r
 \r
   *Argc = Arg;\r
 \r
-  if (*Char == CMD_SEPERATOR) {\r
-    // Replace the command delimeter with null and return pointer to next command line\r
+  if (*Char == CMD_SEPARATOR) {\r
+    // Replace the command delimiter with null and return pointer to next command line\r
     *Char = '\0';\r
     return ++Char;\r
   }\r
@@ -226,12 +231,12 @@ ParseArguments (
 \r
 /**\r
   Return a keypress or optionally timeout if a timeout value was passed in.\r
-  An optional callback funciton is called evey second when waiting for a\r
+  An optional callback function is called every second when waiting for a\r
   timeout.\r
 \r
   @param  Key           EFI Key information returned\r
   @param  TimeoutInSec  Number of seconds to wait to timeout\r
-  @param  CallBack      Callback called every second during the timeout wait \r
+  @param  CallBack      Callback called every second during the timeout wait\r
 \r
   @return EFI_SUCCESS  Key was returned\r
   @return EFI_TIMEOUT  If the TimoutInSec expired\r
@@ -270,15 +275,15 @@ EblGetCharKey (
         if (WaitCount == 2) {\r
           gBS->CloseEvent (WaitList[1]);\r
         }\r
-        return EFI_SUCCESS; \r
+        return EFI_SUCCESS;\r
       }\r
       break;\r
 \r
     case 1:\r
-      // Periodic 1 sec timer signaled \r
+      // Periodic 1 sec timer signaled\r
       TimeoutInSec--;\r
       if (CallBack != NULL) {\r
-        // Call the users callback function if registered \r
+        // Call the users callback function if registered\r
         CallBack (TimeoutInSec);\r
       }\r
       if (TimeoutInSec == 0) {\r
@@ -289,7 +294,7 @@ EblGetCharKey (
     default:\r
       ASSERT (FALSE);\r
     }\r
-  } \r
+  }\r
 }\r
 \r
 \r
@@ -300,7 +305,7 @@ EblGetCharKey (
   If the use hits Q to quit return TRUE else for any other key return FALSE.\r
   PrefixNewline is used to figure out if a newline is needed before the prompt\r
   string. This depends on the last print done before calling this function.\r
-  CurrentRow is updated by one on a call or set back to zero if a prompt is \r
+  CurrentRow is updated by one on a call or set back to zero if a prompt is\r
   needed.\r
 \r
   @param  CurrentRow  Used to figure out if its the end of the page and updated\r
@@ -344,7 +349,7 @@ EblAnyKeyToContinueQtoQuit (
 \r
 \r
 /**\r
-  Set the text color of the EFI Console. If a zero is passed in reset to \r
+  Set the text color of the EFI Console. If a zero is passed in reset to\r
   default text/background color.\r
 \r
   @param  Attribute   For text and background color\r
@@ -365,14 +370,14 @@ EblSetTextColor (
 \r
 \r
 /**\r
-  Collect the keyboard input for a cmd line. Carage Return, New Line, or ESC\r
+  Collect the keyboard input for a cmd line. Carriage Return, New Line, or ESC\r
   terminates the command line. You can edit the command line via left arrow,\r
-  delete and backspace and they all back up and erase the command line. \r
-  No edit of commnad line is possible without deletion at this time!\r
-  The up arrow and down arrow fill Cmd with information from the history \r
+  delete and backspace and they all back up and erase the command line.\r
+  No edit of command line is possible without deletion at this time!\r
+  The up arrow and down arrow fill Cmd with information from the history\r
   buffer.\r
 \r
-  @param  Cmd         Command line to return \r
+  @param  Cmd         Command line to return\r
   @param  CmdMaxSize  Maximum size of Cmd\r
 \r
   @return The Status of EblGetCharKey()\r
@@ -455,6 +460,45 @@ EblPrintStartupBanner (
 }\r
 \r
 \r
+/**\r
+  Send null requests to all removable media block IO devices so the a media add/remove/change\r
+  can be detected in real before we execute a command.\r
+\r
+  This is mainly due to the fact that the FAT driver does not do this today so you can get stale\r
+  dir commands after an SD Card has been removed.\r
+**/\r
+VOID\r
+EblProbeRemovableMedia (\r
+  VOID\r
+  )\r
+{\r
+  UINTN         Index;\r
+  UINTN         Max;\r
+  EFI_OPEN_FILE *File;\r
+\r
+  //\r
+  // Probe for media insertion/removal in removable media devices\r
+  //\r
+  Max = EfiGetDeviceCounts (EfiOpenBlockIo);\r
+  if (Max != 0) {\r
+    for (Index = 0; Index < Max; Index++) {\r
+      File = EfiDeviceOpenByType (EfiOpenBlockIo, Index);\r
+      if (File != NULL) {\r
+        if (File->FsBlockIoMedia->RemovableMedia) {\r
+          // Probe to see if media is present (or not) or media changed\r
+          //  this causes the ReinstallProtocolInterface() to fire in the\r
+          //  block io driver to update the system about media change events\r
+          File->FsBlockIo->ReadBlocks (File->FsBlockIo, File->FsBlockIo->Media->MediaId, (EFI_LBA)0, 0, NULL);\r
+        }\r
+        EfiClose (File);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
+\r
 /**\r
   Print the prompt for the EBL.\r
 **/\r
@@ -464,7 +508,7 @@ EblPrompt (
   )\r
 {\r
   EblSetTextColor (EFI_YELLOW);\r
-  AsciiPrint ((CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt));\r
+  AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());\r
   EblSetTextColor (0);\r
   AsciiPrint ("%a", ">");\r
 }\r
@@ -472,12 +516,12 @@ EblPrompt (
 \r
 \r
 /**\r
-  Parse a command line and execute the commands. The ; seperator allows \r
+  Parse a command line and execute the commands. The ; separator allows\r
   multiple commands for each command line. Stop processing if one of the\r
   commands returns an error.\r
 \r
   @param  CmdLine          Command Line to process.\r
-  @param  MaxCmdLineSize   MaxSize of the Command line \r
+  @param  MaxCmdLineSize   MaxSize of the Command line\r
 \r
   @return EFI status of the Command\r
 \r
@@ -494,7 +538,7 @@ ProcessCmdLine (
   UINTN               Argc;\r
   CHAR8               *Argv[MAX_ARGS];\r
 \r
-  // Parse the command line. The loop processes commands seperated by ;\r
+  // Parse the command line. The loop processes commands separated by ;\r
   for (Ptr = CmdLine, Status = EFI_SUCCESS; Ptr != NULL;) {\r
     Ptr = ParseArguments (Ptr, &Argc, Argv);\r
     if (Argc != 0) {\r
@@ -506,32 +550,34 @@ ProcessCmdLine (
           // exit command so lets exit\r
           break;\r
         } else if (Status == EFI_TIMEOUT) {\r
-          // pause command got imput so don't process any more cmd on this cmd line\r
+          // pause command got input so don't process any more cmd on this cmd line\r
           break;\r
         } else if (EFI_ERROR (Status)) {\r
           AsciiPrint ("%a returned %r error\n", Cmd->Name, Status);\r
           // if any command fails stop processing CmdLine\r
           break;\r
         }\r
-      } \r
-    } \r
+      } else {\r
+        AsciiPrint ("The command '%a' is not supported.\n", Argv[0]);\r
+      }\r
+    }\r
   }\r
 \r
   return Status;\r
 }\r
\r
+\r
 \r
 \r
 /**\r
-  Embedded Boot Loader (EBL) - A simple EFI command line application for embedded \r
-  devices. PcdEmbeddedAutomaticBootCommand is a complied in commnad line that\r
-  gets executed automatically. The ; seperator allows multiple commands \r
+  Embedded Boot Loader (EBL) - A simple EFI command line application for embedded\r
+  devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that\r
+  gets executed automatically. The ; separator allows multiple commands\r
   for each command line.\r
 \r
   @param  ImageHandle   EFI ImageHandle for this application.\r
   @param  SystemTable   EFI system table\r
 \r
-  @return EFI status of the applicaiton\r
+  @return EFI status of the application\r
 \r
 **/\r
 EFI_STATUS\r
@@ -539,7 +585,7 @@ EFIAPI
 EdkBootLoaderEntry (\r
   IN EFI_HANDLE                            ImageHandle,\r
   IN EFI_SYSTEM_TABLE                      *SystemTable\r
-  ) \r
+  )\r
 {\r
   EFI_STATUS  Status;\r
   CHAR8       CmdLine[MAX_CMD_LINE];\r
@@ -548,7 +594,7 @@ EdkBootLoaderEntry (
   UINTN       CommandLineVariableSize = 0;\r
   EFI_GUID    VendorGuid;\r
 \r
-  // Initialize tables of commnads\r
+  // Initialize tables of commands\r
   EblInitializeCmdTable ();\r
   EblInitializeDeviceCmd ();\r
   EblInitializemdHwDebugCmds ();\r
@@ -558,7 +604,16 @@ EdkBootLoaderEntry (
   EblInitializeScriptCmd ();\r
   EblInitializeExternalCmd ();\r
   EblInitializeNetworkCmd();\r
-  \r
+  EblInitializeVariableCmds ();\r
+\r
+  if (gST->ConOut == NULL) {\r
+    DEBUG((EFI_D_ERROR,"Error: No Console Output\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  // Disable the 5 minute EFI watchdog time so we don't get automatically reset\r
+  gBS->SetWatchdogTimer (0, 0, 0, NULL);\r
+\r
   if (FeaturePcdGet (PcdEmbeddedMacBoot)) {\r
     // A MAC will boot in graphics mode, so turn it back to text here\r
     // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.\r
@@ -567,37 +622,35 @@ EdkBootLoaderEntry (
     // Enable the biggest output screen size possible\r
     gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);\r
 \r
-    // Disable the 5 minute EFI watchdog time so we don't get automatically reset\r
-    gBS->SetWatchdogTimer (0, 0, 0, NULL);\r
   }\r
 \r
   // Save current screen mode\r
   gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows);\r
 \r
   EblPrintStartupBanner ();\r
\r
-  // Parse command line and handle commands seperated by ;\r
+\r
+  // Parse command line and handle commands separated by ;\r
   // The loop prints the prompt gets user input and saves history\r
-  \r
+\r
   // Look for a variable with a default command line, otherwise use the Pcd\r
   ZeroMem(&VendorGuid, sizeof(EFI_GUID));\r
 \r
   Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     CommandLineVariable = AllocatePool(CommandLineVariableSize);\r
-    \r
+\r
     Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);\r
     if (!EFI_ERROR(Status)) {\r
       UnicodeStrToAsciiStr(CommandLineVariable, CmdLine);\r
     }\r
-    \r
+\r
     FreePool(CommandLineVariable);\r
   }\r
-  \r
+\r
   if (EFI_ERROR(Status)) {\r
     AsciiStrCpy (CmdLine, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand));\r
   }\r
-  \r
+\r
   for (;;) {\r
     Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE);\r
     if (Status == EFI_ABORTED) {\r
@@ -610,6 +663,11 @@ EdkBootLoaderEntry (
     EblPrompt ();\r
     GetCmd (CmdLine, MAX_CMD_LINE);\r
     SetCmdHistory (CmdLine);\r
+\r
+    if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) {\r
+      // Probe removable media devices to see if media has been inserted or removed.\r
+      EblProbeRemovableMedia ();\r
+    }\r
   }\r
 }\r
 \r