]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Ebl/Main.c
ArmPlatformPkg: remove EblCmdLib implementation
[mirror_edk2.git] / EmbeddedPkg / Ebl / Main.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Basic command line parser for EBL (Embedded Boot Loader)\r
3\r
60274cca
HT
4 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
50c6a4d2 6 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
2ef2b01e 7\r
60274cca 8 This program and the accompanying materials\r
2ef2b01e
A
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16\r
17**/\r
18\r
19#include "Ebl.h"\r
20\r
21// Globals for command history processing\r
22INTN mCmdHistoryEnd = -1;\r
23INTN mCmdHistoryStart = -1;\r
24INTN mCmdHistoryCurrent = -1;\r
25CHAR8 mCmdHistory[MAX_CMD_HISTORY][MAX_CMD_LINE];\r
26CHAR8 *mCmdBlank = "";\r
27\r
28// Globals to remember current screen geometry\r
29UINTN gScreenColumns;\r
30UINTN gScreenRows;\r
31\r
32// Global to turn on/off breaking commands with prompts before they scroll the screen\r
33BOOLEAN gPageBreak = TRUE;\r
34\r
3402aac7 35VOID\r
2ef2b01e
A
36RingBufferIncrement (\r
37 IN INTN *Value\r
38 )\r
39{\r
40 *Value = *Value + 1;\r
3402aac7 41\r
2ef2b01e
A
42 if (*Value >= MAX_CMD_HISTORY) {\r
43 *Value = 0;\r
44 }\r
45}\r
46\r
47VOID\r
48RingBufferDecrement (\r
49 IN INTN *Value\r
50 )\r
51{\r
52 *Value = *Value - 1;\r
3402aac7 53\r
2ef2b01e
A
54 if (*Value < 0) {\r
55 *Value = MAX_CMD_HISTORY - 1;\r
56 }\r
57}\r
58\r
59/**\r
3402aac7 60 Save this command in the circular history buffer. Older commands are\r
2ef2b01e
A
61 overwritten with newer commands.\r
62\r
63 @param Cmd Command line to archive the history of.\r
64\r
65 @return None\r
66\r
67**/\r
68VOID\r
69SetCmdHistory (\r
70 IN CHAR8 *Cmd\r
71 )\r
72{\r
73 // Don't bother adding empty commands to the list\r
74 if (AsciiStrLen(Cmd) != 0) {\r
3402aac7 75\r
2ef2b01e
A
76 // First entry\r
77 if (mCmdHistoryStart == -1) {\r
78 mCmdHistoryStart = 0;\r
79 mCmdHistoryEnd = 0;\r
80 } else {\r
81 // Record the new command at the next index\r
82 RingBufferIncrement(&mCmdHistoryStart);\r
3402aac7 83\r
2ef2b01e
A
84 // If the next index runs into the end index, shuffle end back by one\r
85 if (mCmdHistoryStart == mCmdHistoryEnd) {\r
86 RingBufferIncrement(&mCmdHistoryEnd);\r
87 }\r
88 }\r
3402aac7 89\r
2ef2b01e 90 // Copy the new command line into the ring buffer\r
5140a6df 91 AsciiStrnCpyS (&mCmdHistory[mCmdHistoryStart][0], MAX_CMD_LINE, Cmd, MAX_CMD_LINE);\r
2ef2b01e 92 }\r
3402aac7 93\r
2ef2b01e 94 // Reset the command history for the next up arrow press\r
3402aac7 95 mCmdHistoryCurrent = mCmdHistoryStart;\r
2ef2b01e
A
96}\r
97\r
98\r
99/**\r
100 Retreave data from the Command History buffer. Direction maps into up arrow\r
101 an down arrow on the command line\r
102\r
103 @param Direction Command forward or back\r
104\r
105 @return The Command history based on the Direction\r
106\r
107**/\r
108CHAR8 *\r
109GetCmdHistory (\r
110 IN UINT16 Direction\r
111 )\r
112{\r
113 CHAR8 *HistoricalCommand = NULL;\r
3402aac7 114\r
2ef2b01e
A
115 // No history yet?\r
116 if (mCmdHistoryCurrent == -1) {\r
117 HistoricalCommand = mCmdBlank;\r
118 goto Exit;\r
119 }\r
3402aac7 120\r
2ef2b01e
A
121 if (Direction == SCAN_UP) {\r
122 HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];\r
3402aac7 123\r
2ef2b01e
A
124 // if we just echoed the last command, hang out there, don't wrap around\r
125 if (mCmdHistoryCurrent == mCmdHistoryEnd) {\r
126 goto Exit;\r
127 }\r
3402aac7 128\r
2ef2b01e
A
129 // otherwise, back up by one\r
130 RingBufferDecrement(&mCmdHistoryCurrent);\r
3402aac7 131\r
2ef2b01e 132 } else if (Direction == SCAN_DOWN) {\r
3402aac7 133\r
2ef2b01e
A
134 // if we last echoed the start command, put a blank prompt out\r
135 if (mCmdHistoryCurrent == mCmdHistoryStart) {\r
136 HistoricalCommand = mCmdBlank;\r
137 goto Exit;\r
138 }\r
3402aac7 139\r
2ef2b01e
A
140 // otherwise increment the current pointer and return that command\r
141 RingBufferIncrement(&mCmdHistoryCurrent);\r
142 RingBufferIncrement(&mCmdHistoryCurrent);\r
3402aac7 143\r
2ef2b01e
A
144 HistoricalCommand = &mCmdHistory[mCmdHistoryCurrent][0];\r
145 RingBufferDecrement(&mCmdHistoryCurrent);\r
146 }\r
147\r
3402aac7 148Exit:\r
2ef2b01e
A
149 return HistoricalCommand;\r
150}\r
151\r
152\r
153/**\r
154 Parse the CmdLine and break it up into Argc (arg count) and Argv (array of\r
7ca9e5a4 155 pointers to each argument). The Cmd buffer is altered and separators are\r
2ef2b01e
A
156 converted to string terminators. This allows Argv to point into CmdLine.\r
157 A CmdLine can support multiple commands. The next command in the command line\r
158 is returned if it exists.\r
159\r
160 @param CmdLine String to parse for a set of commands\r
161 @param Argc Returns the number of arguments in the CmdLine current command\r
162 @param Argv Argc pointers to each string in CmdLine\r
163\r
164 @return Next Command in the command line or NULL if non exists\r
165**/\r
166CHAR8 *\r
167ParseArguments (\r
168 IN CHAR8 *CmdLine,\r
169 OUT UINTN *Argc,\r
170 OUT CHAR8 **Argv\r
171 )\r
172{\r
173 UINTN Arg;\r
174 CHAR8 *Char;\r
175 BOOLEAN LookingForArg;\r
176 BOOLEAN InQuote;\r
177\r
178 *Argc = 0;\r
179 if (AsciiStrLen (CmdLine) == 0) {\r
180 return NULL;\r
181 }\r
182\r
7ca9e5a4 183 // Walk a single command line. A CMD_SEPARATOR allows multiple commands on a single line\r
2ef2b01e
A
184 InQuote = FALSE;\r
185 LookingForArg = TRUE;\r
186 for (Char = CmdLine, Arg = 0; *Char != '\0'; Char++) {\r
7ca9e5a4 187 if (!InQuote && *Char == CMD_SEPARATOR) {\r
2ef2b01e
A
188 break;\r
189 }\r
190\r
fb334ef6 191 // Perform any text conversion here\r
2ef2b01e
A
192 if (*Char == '\t') {\r
193 // TAB to space\r
194 *Char = ' ';\r
195 }\r
196\r
197 if (LookingForArg) {\r
7ca9e5a4 198 // Look for the beginning of an Argv[] entry\r
2ef2b01e
A
199 if (*Char == '"') {\r
200 Argv[Arg++] = ++Char;\r
201 LookingForArg = FALSE;\r
202 InQuote = TRUE;\r
203 } else if (*Char != ' ') {\r
204 Argv[Arg++] = Char;\r
205 LookingForArg = FALSE;\r
3402aac7 206 }\r
2ef2b01e
A
207 } else {\r
208 // Looking for the terminator of an Argv[] entry\r
fb334ef6 209 if (!InQuote && (*Char == ' ')) {\r
2ef2b01e
A
210 *Char = '\0';\r
211 LookingForArg = TRUE;\r
fb334ef6 212 } else if (!InQuote && (*Char == '"') && (*(Char-1) != '\\')) {\r
213 InQuote = TRUE;\r
214 } else if (InQuote && (*Char == '"') && (*(Char-1) != '\\')) {\r
215 *Char = '\0';\r
216 InQuote = FALSE;\r
2ef2b01e 217 }\r
3402aac7 218 }\r
2ef2b01e
A
219 }\r
220\r
221 *Argc = Arg;\r
222\r
7ca9e5a4 223 if (*Char == CMD_SEPARATOR) {\r
224 // Replace the command delimiter with null and return pointer to next command line\r
2ef2b01e
A
225 *Char = '\0';\r
226 return ++Char;\r
227 }\r
228\r
229 return NULL;\r
230}\r
231\r
232\r
233/**\r
234 Return a keypress or optionally timeout if a timeout value was passed in.\r
7ca9e5a4 235 An optional callback function is called every second when waiting for a\r
2ef2b01e
A
236 timeout.\r
237\r
238 @param Key EFI Key information returned\r
239 @param TimeoutInSec Number of seconds to wait to timeout\r
3402aac7 240 @param CallBack Callback called every second during the timeout wait\r
2ef2b01e
A
241\r
242 @return EFI_SUCCESS Key was returned\r
243 @return EFI_TIMEOUT If the TimoutInSec expired\r
244\r
245**/\r
246EFI_STATUS\r
50c6a4d2 247EFIAPI\r
2ef2b01e
A
248EblGetCharKey (\r
249 IN OUT EFI_INPUT_KEY *Key,\r
250 IN UINTN TimeoutInSec,\r
251 IN EBL_GET_CHAR_CALL_BACK CallBack OPTIONAL\r
252 )\r
253{\r
254 EFI_STATUS Status;\r
255 UINTN WaitCount;\r
256 UINTN WaitIndex;\r
257 EFI_EVENT WaitList[2];\r
258\r
259 WaitCount = 1;\r
260 WaitList[0] = gST->ConIn->WaitForKey;\r
261 if (TimeoutInSec != 0) {\r
262 // Create a time event for 1 sec duration if we have a timeout\r
263 gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &WaitList[1]);\r
264 gBS->SetTimer (WaitList[1], TimerPeriodic, EFI_SET_TIMER_TO_SECOND);\r
265 WaitCount++;\r
266 }\r
267\r
268 for (;;) {\r
269 Status = gBS->WaitForEvent (WaitCount, WaitList, &WaitIndex);\r
270 ASSERT_EFI_ERROR (Status);\r
271\r
272 switch (WaitIndex) {\r
273 case 0:\r
274 // Key event signaled\r
275 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);\r
276 if (!EFI_ERROR (Status)) {\r
277 if (WaitCount == 2) {\r
278 gBS->CloseEvent (WaitList[1]);\r
279 }\r
3402aac7 280 return EFI_SUCCESS;\r
2ef2b01e
A
281 }\r
282 break;\r
283\r
284 case 1:\r
3402aac7 285 // Periodic 1 sec timer signaled\r
2ef2b01e
A
286 TimeoutInSec--;\r
287 if (CallBack != NULL) {\r
3402aac7 288 // Call the users callback function if registered\r
2ef2b01e
A
289 CallBack (TimeoutInSec);\r
290 }\r
291 if (TimeoutInSec == 0) {\r
292 gBS->CloseEvent (WaitList[1]);\r
293 return EFI_TIMEOUT;\r
294 }\r
295 break;\r
296 default:\r
297 ASSERT (FALSE);\r
298 }\r
3402aac7 299 }\r
2ef2b01e
A
300}\r
301\r
302\r
303/**\r
304 This routine is used prevent command output data from scrolling off the end\r
305 of the screen. The global gPageBreak is used to turn on or off this feature.\r
306 If the CurrentRow is near the end of the screen pause and print out a prompt\r
307 If the use hits Q to quit return TRUE else for any other key return FALSE.\r
308 PrefixNewline is used to figure out if a newline is needed before the prompt\r
309 string. This depends on the last print done before calling this function.\r
3402aac7 310 CurrentRow is updated by one on a call or set back to zero if a prompt is\r
2ef2b01e
A
311 needed.\r
312\r
313 @param CurrentRow Used to figure out if its the end of the page and updated\r
314 @param PrefixNewline Did previous print issue a newline\r
315\r
316 @return TRUE if Q was hit to quit, FALSE in all other cases.\r
317\r
318**/\r
319BOOLEAN\r
50c6a4d2 320EFIAPI\r
2ef2b01e
A
321EblAnyKeyToContinueQtoQuit (\r
322 IN UINTN *CurrentRow,\r
323 IN BOOLEAN PrefixNewline\r
324 )\r
325{\r
326 EFI_INPUT_KEY InputKey;\r
327\r
328 if (!gPageBreak) {\r
329 // global disable for this feature\r
330 return FALSE;\r
331 }\r
332\r
333 if (*CurrentRow >= (gScreenRows - 2)) {\r
334 if (PrefixNewline) {\r
335 AsciiPrint ("\n");\r
336 }\r
337 AsciiPrint ("Any key to continue (Q to quit): ");\r
338 EblGetCharKey (&InputKey, 0, NULL);\r
339 AsciiPrint ("\n");\r
340\r
341 // Time to promt to stop the screen. We have to leave space for the prompt string\r
342 *CurrentRow = 0;\r
343 if (InputKey.UnicodeChar == 'Q' || InputKey.UnicodeChar == 'q') {\r
344 return TRUE;\r
345 }\r
346 } else {\r
347 *CurrentRow += 1;\r
348 }\r
349\r
350 return FALSE;\r
351}\r
352\r
353\r
354/**\r
3402aac7 355 Set the text color of the EFI Console. If a zero is passed in reset to\r
2ef2b01e
A
356 default text/background color.\r
357\r
358 @param Attribute For text and background color\r
359\r
360**/\r
361VOID\r
362EblSetTextColor (\r
363 UINTN Attribute\r
364 )\r
365{\r
366 if (Attribute == 0) {\r
367 // Set the text color back to default\r
368 Attribute = (UINTN)PcdGet32 (PcdEmbeddedDefaultTextColor);\r
369 }\r
370\r
371 gST->ConOut->SetAttribute (gST->ConOut, Attribute);\r
372}\r
373\r
374\r
375/**\r
7ca9e5a4 376 Collect the keyboard input for a cmd line. Carriage Return, New Line, or ESC\r
2ef2b01e 377 terminates the command line. You can edit the command line via left arrow,\r
3402aac7 378 delete and backspace and they all back up and erase the command line.\r
7ca9e5a4 379 No edit of command line is possible without deletion at this time!\r
3402aac7 380 The up arrow and down arrow fill Cmd with information from the history\r
2ef2b01e
A
381 buffer.\r
382\r
3402aac7 383 @param Cmd Command line to return\r
2ef2b01e
A
384 @param CmdMaxSize Maximum size of Cmd\r
385\r
386 @return The Status of EblGetCharKey()\r
387\r
388**/\r
389EFI_STATUS\r
390GetCmd (\r
391 IN OUT CHAR8 *Cmd,\r
392 IN UINTN CmdMaxSize\r
393 )\r
394{\r
395 EFI_STATUS Status;\r
396 UINTN Index;\r
397 UINTN Index2;\r
398 CHAR8 Char;\r
399 CHAR8 *History;\r
400 EFI_INPUT_KEY Key;\r
401\r
402 for (Index = 0; Index < CmdMaxSize - 1;) {\r
403 Status = EblGetCharKey (&Key, 0, NULL);\r
404 if (EFI_ERROR (Status)) {\r
405 Cmd[Index] = '\0';\r
406 AsciiPrint ("\n");\r
407 return Status;\r
408 }\r
409\r
410 Char = (CHAR8)Key.UnicodeChar;\r
411 if ((Char == '\n') || (Char == '\r') || (Char == 0x7f)) {\r
412 Cmd[Index] = '\0';\r
413 if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {\r
414 AsciiPrint ("\n\r");\r
415 }\r
416 return EFI_SUCCESS;\r
417 } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){\r
418 if (Index != 0) {\r
419 Index--;\r
420 //\r
421 // Update the display\r
422 //\r
423 AsciiPrint ("\b \b");\r
424 }\r
425 } else if ((Key.ScanCode == SCAN_UP) || Key.ScanCode == SCAN_DOWN) {\r
426 History = GetCmdHistory (Key.ScanCode);\r
427 //\r
428 // Clear display line\r
429 //\r
430 for (Index2 = 0; Index2 < Index; Index2++) {\r
431 AsciiPrint ("\b \b");\r
432 }\r
433 AsciiPrint (History);\r
434 Index = AsciiStrLen (History);\r
5140a6df 435 AsciiStrnCpyS (Cmd, CmdMaxSize, History, CmdMaxSize);\r
2ef2b01e
A
436 } else {\r
437 Cmd[Index++] = Char;\r
438 if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {\r
439 AsciiPrint ("%c", Char);\r
440 }\r
441 }\r
442 }\r
443\r
444 return EFI_SUCCESS;\r
445}\r
446\r
447\r
448/**\r
449 Print the boot up banner for the EBL.\r
450**/\r
451VOID\r
452EblPrintStartupBanner (\r
453 VOID\r
454 )\r
455{\r
456 AsciiPrint ("Embedded Boot Loader (");\r
457 EblSetTextColor (EFI_YELLOW);\r
458 AsciiPrint ("EBL");\r
459 EblSetTextColor (0);\r
460 AsciiPrint (") prototype. Built at %a on %a\n",__TIME__, __DATE__);\r
461 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");\r
fc35d135 462 AsciiPrint ("Please send feedback to edk2-devel@lists.sourceforge.net\n");\r
2ef2b01e
A
463}\r
464\r
465\r
884366cf 466/**\r
467 Send null requests to all removable media block IO devices so the a media add/remove/change\r
3402aac7 468 can be detected in real before we execute a command.\r
884366cf 469\r
3402aac7 470 This is mainly due to the fact that the FAT driver does not do this today so you can get stale\r
884366cf 471 dir commands after an SD Card has been removed.\r
472**/\r
473VOID\r
474EblProbeRemovableMedia (\r
475 VOID\r
476 )\r
477{\r
478 UINTN Index;\r
479 UINTN Max;\r
480 EFI_OPEN_FILE *File;\r
481\r
482 //\r
483 // Probe for media insertion/removal in removable media devices\r
484 //\r
485 Max = EfiGetDeviceCounts (EfiOpenBlockIo);\r
486 if (Max != 0) {\r
487 for (Index = 0; Index < Max; Index++) {\r
488 File = EfiDeviceOpenByType (EfiOpenBlockIo, Index);\r
489 if (File != NULL) {\r
490 if (File->FsBlockIoMedia->RemovableMedia) {\r
491 // Probe to see if media is present (or not) or media changed\r
492 // this causes the ReinstallProtocolInterface() to fire in the\r
493 // block io driver to update the system about media change events\r
494 File->FsBlockIo->ReadBlocks (File->FsBlockIo, File->FsBlockIo->Media->MediaId, (EFI_LBA)0, 0, NULL);\r
495 }\r
496 EfiClose (File);\r
497 }\r
498 }\r
499 }\r
500}\r
501\r
502\r
503\r
504\r
2ef2b01e
A
505/**\r
506 Print the prompt for the EBL.\r
507**/\r
508VOID\r
509EblPrompt (\r
510 VOID\r
511 )\r
512{\r
513 EblSetTextColor (EFI_YELLOW);\r
e6b3b508 514 AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());\r
2ef2b01e
A
515 EblSetTextColor (0);\r
516 AsciiPrint ("%a", ">");\r
517}\r
518\r
519\r
520\r
521/**\r
7ca9e5a4 522 Parse a command line and execute the commands. The ; separator allows\r
2ef2b01e
A
523 multiple commands for each command line. Stop processing if one of the\r
524 commands returns an error.\r
525\r
526 @param CmdLine Command Line to process.\r
3402aac7 527 @param MaxCmdLineSize MaxSize of the Command line\r
2ef2b01e
A
528\r
529 @return EFI status of the Command\r
530\r
531**/\r
532EFI_STATUS\r
533ProcessCmdLine (\r
534 IN CHAR8 *CmdLine,\r
535 IN UINTN MaxCmdLineSize\r
536 )\r
537{\r
538 EFI_STATUS Status;\r
539 EBL_COMMAND_TABLE *Cmd;\r
540 CHAR8 *Ptr;\r
541 UINTN Argc;\r
542 CHAR8 *Argv[MAX_ARGS];\r
543\r
7ca9e5a4 544 // Parse the command line. The loop processes commands separated by ;\r
2ef2b01e
A
545 for (Ptr = CmdLine, Status = EFI_SUCCESS; Ptr != NULL;) {\r
546 Ptr = ParseArguments (Ptr, &Argc, Argv);\r
547 if (Argc != 0) {\r
548 Cmd = EblGetCommand (Argv[0]);\r
549 if (Cmd != NULL) {\r
550 // Execute the Command!\r
551 Status = Cmd->Command (Argc, Argv);\r
552 if (Status == EFI_ABORTED) {\r
553 // exit command so lets exit\r
554 break;\r
555 } else if (Status == EFI_TIMEOUT) {\r
7ca9e5a4 556 // pause command got input so don't process any more cmd on this cmd line\r
2ef2b01e
A
557 break;\r
558 } else if (EFI_ERROR (Status)) {\r
559 AsciiPrint ("%a returned %r error\n", Cmd->Name, Status);\r
560 // if any command fails stop processing CmdLine\r
561 break;\r
562 }\r
5817449f 563 } else {\r
564 AsciiPrint ("The command '%a' is not supported.\n", Argv[0]);\r
3402aac7
RC
565 }\r
566 }\r
2ef2b01e
A
567 }\r
568\r
569 return Status;\r
570}\r
3402aac7 571\r
2ef2b01e
A
572\r
573\r
574/**\r
3402aac7 575 Embedded Boot Loader (EBL) - A simple EFI command line application for embedded\r
7ca9e5a4 576 devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that\r
577 gets executed automatically. The ; separator allows multiple commands\r
2ef2b01e
A
578 for each command line.\r
579\r
580 @param ImageHandle EFI ImageHandle for this application.\r
581 @param SystemTable EFI system table\r
582\r
7ca9e5a4 583 @return EFI status of the application\r
2ef2b01e
A
584\r
585**/\r
586EFI_STATUS\r
587EFIAPI\r
588EdkBootLoaderEntry (\r
589 IN EFI_HANDLE ImageHandle,\r
590 IN EFI_SYSTEM_TABLE *SystemTable\r
3402aac7 591 )\r
2ef2b01e
A
592{\r
593 EFI_STATUS Status;\r
594 CHAR8 CmdLine[MAX_CMD_LINE];\r
595 CHAR16 *CommandLineVariable = NULL;\r
596 CHAR16 *CommandLineVariableName = L"default-cmdline";\r
597 UINTN CommandLineVariableSize = 0;\r
598 EFI_GUID VendorGuid;\r
599\r
7ca9e5a4 600 // Initialize tables of commands\r
2ef2b01e
A
601 EblInitializeCmdTable ();\r
602 EblInitializeDeviceCmd ();\r
603 EblInitializemdHwDebugCmds ();\r
604 EblInitializemdHwIoDebugCmds ();\r
605 EblInitializeDirCmd ();\r
606 EblInitializeHobCmd ();\r
607 EblInitializeScriptCmd ();\r
608 EblInitializeExternalCmd ();\r
609 EblInitializeNetworkCmd();\r
fb334ef6 610 EblInitializeVariableCmds ();\r
3402aac7 611\r
d60b4c43 612 if (gST->ConOut == NULL) {\r
7ca9e5a4 613 DEBUG((EFI_D_ERROR,"Error: No Console Output\n"));\r
d60b4c43 614 return EFI_NOT_READY;\r
615 }\r
616\r
16ccac42 617 // Disable the 5 minute EFI watchdog time so we don't get automatically reset\r
618 gBS->SetWatchdogTimer (0, 0, 0, NULL);\r
619\r
2ef2b01e
A
620 if (FeaturePcdGet (PcdEmbeddedMacBoot)) {\r
621 // A MAC will boot in graphics mode, so turn it back to text here\r
622 // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.\r
623 // DisableQuietBoot ();\r
624\r
625 // Enable the biggest output screen size possible\r
626 gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);\r
627\r
2ef2b01e
A
628 }\r
629\r
630 // Save current screen mode\r
631 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows);\r
632\r
633 EblPrintStartupBanner ();\r
3402aac7 634\r
7ca9e5a4 635 // Parse command line and handle commands separated by ;\r
2ef2b01e 636 // The loop prints the prompt gets user input and saves history\r
3402aac7 637\r
2ef2b01e
A
638 // Look for a variable with a default command line, otherwise use the Pcd\r
639 ZeroMem(&VendorGuid, sizeof(EFI_GUID));\r
640\r
641 Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);\r
642 if (Status == EFI_BUFFER_TOO_SMALL) {\r
643 CommandLineVariable = AllocatePool(CommandLineVariableSize);\r
3402aac7 644\r
2ef2b01e
A
645 Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);\r
646 if (!EFI_ERROR(Status)) {\r
5140a6df 647 UnicodeStrToAsciiStrS (CommandLineVariable, CmdLine, MAX_CMD_LINE);\r
2ef2b01e 648 }\r
3402aac7 649\r
2ef2b01e
A
650 FreePool(CommandLineVariable);\r
651 }\r
3402aac7 652\r
2ef2b01e 653 if (EFI_ERROR(Status)) {\r
5140a6df 654 AsciiStrCpyS (CmdLine, MAX_CMD_LINE, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand));\r
2ef2b01e 655 }\r
3402aac7 656\r
2ef2b01e
A
657 for (;;) {\r
658 Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE);\r
659 if (Status == EFI_ABORTED) {\r
660 // if a command returns EFI_ABORTED then exit the EBL\r
661 EblShutdownExternalCmdTable ();\r
662 return EFI_SUCCESS;\r
663 }\r
664\r
665 // get the command line from the user\r
666 EblPrompt ();\r
667 GetCmd (CmdLine, MAX_CMD_LINE);\r
668 SetCmdHistory (CmdLine);\r
884366cf 669\r
670 if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) {\r
671 // Probe removable media devices to see if media has been inserted or removed.\r
672 EblProbeRemovableMedia ();\r
673 }\r
2ef2b01e
A
674 }\r
675}\r
676\r
677\r