// 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
)\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
{\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
} 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
)\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
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
} 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
\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
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
default:\r
ASSERT (FALSE);\r
}\r
- } \r
+ }\r
}\r
\r
\r
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
\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
\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
}\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
)\r
{\r
EblSetTextColor (EFI_YELLOW);\r
- AsciiPrint ((CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());\r
+ AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());\r
EblSetTextColor (0);\r
AsciiPrint ("%a", ">");\r
}\r
\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
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
// 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
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
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
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
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
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