]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidFastboot / AndroidFastbootApp.c
CommitLineData
f6755908
OM
1/** @file\r
2\r
3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
4\r
878b807a 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
f6755908
OM
6\r
7**/\r
8\r
9#include "AndroidFastbootApp.h"\r
10\r
11#include <Protocol/AndroidFastbootTransport.h>\r
12#include <Protocol/AndroidFastbootPlatform.h>\r
13#include <Protocol/SimpleTextOut.h>\r
14#include <Protocol/SimpleTextIn.h>\r
15\r
16#include <Library/PcdLib.h>\r
17#include <Library/UefiRuntimeServicesTableLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/UefiApplicationEntryPoint.h>\r
21#include <Library/PrintLib.h>\r
22\r
23/*\r
24 * UEFI Application using the FASTBOOT_TRANSPORT_PROTOCOL and\r
25 * FASTBOOT_PLATFORM_PROTOCOL to implement the Android Fastboot protocol.\r
26 */\r
27\r
e7108d0e
MK
28STATIC FASTBOOT_TRANSPORT_PROTOCOL *mTransport;\r
29STATIC FASTBOOT_PLATFORM_PROTOCOL *mPlatform;\r
f6755908 30\r
e7108d0e 31STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;\r
f6755908
OM
32\r
33typedef enum {\r
34 ExpectCmdState,\r
35 ExpectDataState,\r
36 FastbootStateMax\r
37} ANDROID_FASTBOOT_STATE;\r
38\r
e7108d0e 39STATIC ANDROID_FASTBOOT_STATE mState = ExpectCmdState;\r
f6755908
OM
40\r
41// When in ExpectDataState, the number of bytes of data to expect:\r
e7108d0e 42STATIC UINT64 mNumDataBytes;\r
f6755908 43// .. and the number of bytes so far received this data phase\r
e7108d0e 44STATIC UINT64 mBytesReceivedSoFar;\r
f6755908 45// .. and the buffer to save data into\r
e7108d0e 46STATIC UINT8 *mDataBuffer = NULL;\r
f6755908
OM
47\r
48// Event notify functions, from which gBS->Exit shouldn't be called, can signal\r
49// this event when the application should exit\r
e7108d0e 50STATIC EFI_EVENT mFinishedEvent;\r
f6755908 51\r
e7108d0e 52STATIC EFI_EVENT mFatalSendErrorEvent;\r
f6755908
OM
53\r
54// This macro uses sizeof - only use it on arrays (i.e. string literals)\r
e7108d0e 55#define SEND_LITERAL(Str) mTransport->Send ( \\r
f6755908
OM
56 sizeof (Str) - 1, \\r
57 Str, \\r
58 &mFatalSendErrorEvent \\r
59 )\r
e7108d0e 60#define MATCH_CMD_LITERAL(Cmd, Buf) !AsciiStrnCmp (Cmd, Buf, sizeof (Cmd) - 1)\r
f6755908 61\r
e7108d0e 62#define IS_LOWERCASE_ASCII(Char) (Char >= 'a' && Char <= 'z')\r
f6755908 63\r
e7108d0e
MK
64#define FASTBOOT_STRING_MAX_LENGTH 256\r
65#define FASTBOOT_COMMAND_MAX_LENGTH 64\r
f6755908
OM
66\r
67STATIC\r
68VOID\r
69HandleGetVar (\r
e7108d0e 70 IN CHAR8 *CmdArg\r
f6755908
OM
71 )\r
72{\r
e7108d0e
MK
73 CHAR8 Response[FASTBOOT_COMMAND_MAX_LENGTH + 1] = "OKAY";\r
74 EFI_STATUS Status;\r
f6755908
OM
75\r
76 // Respond to getvar:version with 0.4 (version of Fastboot protocol)\r
e7108d0e 77 if (!AsciiStrnCmp ("version", CmdArg, sizeof ("version") - 1)) {\r
f6755908
OM
78 SEND_LITERAL ("OKAY" ANDROID_FASTBOOT_VERSION);\r
79 } else {\r
80 // All other variables are assumed to be platform specific\r
81 Status = mPlatform->GetVar (CmdArg, Response + 4);\r
82 if (EFI_ERROR (Status)) {\r
83 SEND_LITERAL ("FAILSomething went wrong when looking up the variable");\r
84 } else {\r
85 mTransport->Send (AsciiStrLen (Response), Response, &mFatalSendErrorEvent);\r
86 }\r
87 }\r
88}\r
89\r
90STATIC\r
91VOID\r
92HandleDownload (\r
e7108d0e 93 IN CHAR8 *NumBytesString\r
f6755908
OM
94 )\r
95{\r
e7108d0e
MK
96 CHAR8 Response[13];\r
97 CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];\r
f6755908
OM
98\r
99 // Argument is 8-character ASCII string hex representation of number of bytes\r
100 // that will be sent in the data phase.\r
101 // Response is "DATA" + that same 8-character string.\r
102\r
103 // Replace any previously downloaded data\r
104 if (mDataBuffer != NULL) {\r
105 FreePool (mDataBuffer);\r
106 mDataBuffer = NULL;\r
107 }\r
108\r
109 // Parse out number of data bytes to expect\r
110 mNumDataBytes = AsciiStrHexToUint64 (NumBytesString);\r
111 if (mNumDataBytes == 0) {\r
112 mTextOut->OutputString (mTextOut, L"ERROR: Fail to get the number of bytes to download.\r\n");\r
113 SEND_LITERAL ("FAILFailed to get the number of bytes to download");\r
114 return;\r
115 }\r
116\r
117 UnicodeSPrint (OutputString, sizeof (OutputString), L"Downloading %d bytes\r\n", mNumDataBytes);\r
118 mTextOut->OutputString (mTextOut, OutputString);\r
119\r
120 mDataBuffer = AllocatePool (mNumDataBytes);\r
121 if (mDataBuffer == NULL) {\r
122 SEND_LITERAL ("FAILNot enough memory");\r
123 } else {\r
31090876 124 ZeroMem (Response, sizeof Response);\r
e7108d0e
MK
125 AsciiSPrint (\r
126 Response,\r
127 sizeof Response,\r
128 "DATA%x",\r
129 (UINT32)mNumDataBytes\r
130 );\r
31090876 131 mTransport->Send (sizeof Response - 1, Response, &mFatalSendErrorEvent);\r
f6755908 132\r
e7108d0e 133 mState = ExpectDataState;\r
f6755908
OM
134 mBytesReceivedSoFar = 0;\r
135 }\r
136}\r
137\r
138STATIC\r
139VOID\r
140HandleFlash (\r
e7108d0e 141 IN CHAR8 *PartitionName\r
f6755908
OM
142 )\r
143{\r
144 EFI_STATUS Status;\r
145 CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];\r
146\r
147 // Build output string\r
148 UnicodeSPrint (OutputString, sizeof (OutputString), L"Flashing partition %a\r\n", PartitionName);\r
149 mTextOut->OutputString (mTextOut, OutputString);\r
150\r
151 if (mDataBuffer == NULL) {\r
152 // Doesn't look like we were sent any data\r
153 SEND_LITERAL ("FAILNo data to flash");\r
154 return;\r
155 }\r
156\r
157 Status = mPlatform->FlashPartition (\r
158 PartitionName,\r
159 mNumDataBytes,\r
160 mDataBuffer\r
161 );\r
162 if (Status == EFI_NOT_FOUND) {\r
163 SEND_LITERAL ("FAILNo such partition.");\r
164 mTextOut->OutputString (mTextOut, L"No such partition.\r\n");\r
165 } else if (EFI_ERROR (Status)) {\r
166 SEND_LITERAL ("FAILError flashing partition.");\r
167 mTextOut->OutputString (mTextOut, L"Error flashing partition.\r\n");\r
a1878955 168 DEBUG ((DEBUG_ERROR, "Couldn't flash image: %r\n", Status));\r
f6755908
OM
169 } else {\r
170 mTextOut->OutputString (mTextOut, L"Done.\r\n");\r
171 SEND_LITERAL ("OKAY");\r
172 }\r
173}\r
174\r
175STATIC\r
176VOID\r
177HandleErase (\r
e7108d0e 178 IN CHAR8 *PartitionName\r
f6755908
OM
179 )\r
180{\r
181 EFI_STATUS Status;\r
182 CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];\r
183\r
184 // Build output string\r
185 UnicodeSPrint (OutputString, sizeof (OutputString), L"Erasing partition %a\r\n", PartitionName);\r
186 mTextOut->OutputString (mTextOut, OutputString);\r
187\r
188 Status = mPlatform->ErasePartition (PartitionName);\r
189 if (EFI_ERROR (Status)) {\r
190 SEND_LITERAL ("FAILCheck device console.");\r
a1878955 191 DEBUG ((DEBUG_ERROR, "Couldn't erase image: %r\n", Status));\r
f6755908
OM
192 } else {\r
193 SEND_LITERAL ("OKAY");\r
194 }\r
195}\r
196\r
197STATIC\r
198VOID\r
199HandleBoot (\r
200 VOID\r
201 )\r
202{\r
e7108d0e 203 EFI_STATUS Status;\r
f6755908
OM
204\r
205 mTextOut->OutputString (mTextOut, L"Booting downloaded image\r\n");\r
206\r
207 if (mDataBuffer == NULL) {\r
208 // Doesn't look like we were sent any data\r
209 SEND_LITERAL ("FAILNo image in memory");\r
210 return;\r
211 }\r
212\r
213 // We don't really have any choice but to report success, because once we\r
214 // boot we lose control of the system.\r
215 SEND_LITERAL ("OKAY");\r
216\r
217 Status = BootAndroidBootImg (mNumDataBytes, mDataBuffer);\r
218 if (EFI_ERROR (Status)) {\r
a1878955 219 DEBUG ((DEBUG_ERROR, "Failed to boot downloaded image: %r\n", Status));\r
f6755908 220 }\r
e7108d0e 221\r
f6755908
OM
222 // We shouldn't get here\r
223}\r
224\r
225STATIC\r
226VOID\r
227HandleOemCommand (\r
e7108d0e 228 IN CHAR8 *Command\r
f6755908
OM
229 )\r
230{\r
231 EFI_STATUS Status;\r
232\r
233 Status = mPlatform->DoOemCommand (Command);\r
234 if (Status == EFI_NOT_FOUND) {\r
235 SEND_LITERAL ("FAILOEM Command not recognised.");\r
236 } else if (Status == EFI_DEVICE_ERROR) {\r
237 SEND_LITERAL ("FAILError while executing command");\r
238 } else if (EFI_ERROR (Status)) {\r
239 SEND_LITERAL ("FAIL");\r
240 } else {\r
241 SEND_LITERAL ("OKAY");\r
242 }\r
243}\r
244\r
245STATIC\r
246VOID\r
247AcceptCmd (\r
248 IN UINTN Size,\r
e7108d0e 249 IN CONST CHAR8 *Data\r
f6755908
OM
250 )\r
251{\r
e7108d0e 252 CHAR8 Command[FASTBOOT_COMMAND_MAX_LENGTH + 1];\r
f6755908
OM
253\r
254 // Max command size is 64 bytes\r
255 if (Size > FASTBOOT_COMMAND_MAX_LENGTH) {\r
256 SEND_LITERAL ("FAILCommand too large");\r
257 return;\r
258 }\r
259\r
260 // Commands aren't null-terminated. Let's get a null-terminated version.\r
31090876 261 AsciiStrnCpyS (Command, sizeof Command, Data, Size);\r
f6755908
OM
262\r
263 // Parse command\r
264 if (MATCH_CMD_LITERAL ("getvar", Command)) {\r
265 HandleGetVar (Command + sizeof ("getvar"));\r
266 } else if (MATCH_CMD_LITERAL ("download", Command)) {\r
267 HandleDownload (Command + sizeof ("download"));\r
268 } else if (MATCH_CMD_LITERAL ("verify", Command)) {\r
269 SEND_LITERAL ("FAILNot supported");\r
270 } else if (MATCH_CMD_LITERAL ("flash", Command)) {\r
271 HandleFlash (Command + sizeof ("flash"));\r
272 } else if (MATCH_CMD_LITERAL ("erase", Command)) {\r
273 HandleErase (Command + sizeof ("erase"));\r
274 } else if (MATCH_CMD_LITERAL ("boot", Command)) {\r
275 HandleBoot ();\r
276 } else if (MATCH_CMD_LITERAL ("continue", Command)) {\r
277 SEND_LITERAL ("OKAY");\r
278 mTextOut->OutputString (mTextOut, L"Received 'continue' command. Exiting Fastboot mode\r\n");\r
279\r
280 gBS->SignalEvent (mFinishedEvent);\r
281 } else if (MATCH_CMD_LITERAL ("reboot", Command)) {\r
282 if (MATCH_CMD_LITERAL ("reboot-booloader", Command)) {\r
283 // fastboot_protocol.txt:\r
284 // "reboot-bootloader Reboot back into the bootloader."\r
285 // I guess this means reboot back into fastboot mode to save the user\r
286 // having to do whatever they did to get here again.\r
287 // Here we just reboot normally.\r
288 SEND_LITERAL ("INFOreboot-bootloader not supported, rebooting normally.");\r
289 }\r
e7108d0e 290\r
f6755908
OM
291 SEND_LITERAL ("OKAY");\r
292 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
293\r
294 // Shouldn't get here\r
a1878955 295 DEBUG ((DEBUG_ERROR, "Fastboot: gRT->ResetSystem didn't work\n"));\r
f6755908
OM
296 } else if (MATCH_CMD_LITERAL ("powerdown", Command)) {\r
297 SEND_LITERAL ("OKAY");\r
298 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
299\r
300 // Shouldn't get here\r
a1878955 301 DEBUG ((DEBUG_ERROR, "Fastboot: gRT->ResetSystem didn't work\n"));\r
f6755908
OM
302 } else if (MATCH_CMD_LITERAL ("oem", Command)) {\r
303 // The "oem" command isn't in the specification, but it was observed in the\r
304 // wild, followed by a space, followed by the actual command.\r
305 HandleOemCommand (Command + sizeof ("oem"));\r
306 } else if (IS_LOWERCASE_ASCII (Command[0])) {\r
307 // Commands starting with lowercase ASCII characters are reserved for the\r
308 // Fastboot protocol. If we don't recognise it, it's probably the future\r
c6a72cd7 309 // and there are new commands in the protocol.\r
f6755908
OM
310 // (By the way, the "oem" command mentioned above makes this reservation\r
311 // redundant, but we handle it here to be spec-compliant)\r
312 SEND_LITERAL ("FAILCommand not recognised. Check Fastboot version.");\r
313 } else {\r
314 HandleOemCommand (Command);\r
315 }\r
316}\r
317\r
318STATIC\r
319VOID\r
320AcceptData (\r
321 IN UINTN Size,\r
e7108d0e 322 IN VOID *Data\r
f6755908
OM
323 )\r
324{\r
e7108d0e
MK
325 UINT32 RemainingBytes = mNumDataBytes - mBytesReceivedSoFar;\r
326 CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];\r
327 STATIC UINTN Count = 0;\r
f6755908
OM
328\r
329 // Protocol doesn't say anything about sending extra data so just ignore it.\r
330 if (Size > RemainingBytes) {\r
331 Size = RemainingBytes;\r
332 }\r
333\r
334 CopyMem (&mDataBuffer[mBytesReceivedSoFar], Data, Size);\r
335\r
336 mBytesReceivedSoFar += Size;\r
337\r
338 // Show download progress. Don't do it for every packet as outputting text\r
339 // might be time consuming - do it on the last packet and on every 32nd packet\r
e7108d0e 340 if (((Count++ % 32) == 0) || (Size == RemainingBytes)) {\r
f6755908
OM
341 // (Note no newline in format string - it will overwrite the line each time)\r
342 UnicodeSPrint (\r
343 OutputString,\r
344 sizeof (OutputString),\r
345 L"\r%8d / %8d bytes downloaded (%d%%)",\r
346 mBytesReceivedSoFar,\r
347 mNumDataBytes,\r
348 (mBytesReceivedSoFar * 100) / mNumDataBytes // percentage\r
349 );\r
350 mTextOut->OutputString (mTextOut, OutputString);\r
351 }\r
352\r
353 if (mBytesReceivedSoFar == mNumDataBytes) {\r
354 // Download finished.\r
355\r
356 mTextOut->OutputString (mTextOut, L"\r\n");\r
357 SEND_LITERAL ("OKAY");\r
358 mState = ExpectCmdState;\r
359 }\r
360}\r
361\r
362/*\r
363 This is the NotifyFunction passed to CreateEvent in the FastbootAppEntryPoint\r
364 It will be called by the UEFI event framework when the transport protocol\r
365 implementation signals that data has been received from the Fastboot host.\r
366 The parameters are ignored.\r
367*/\r
368STATIC\r
369VOID\r
370DataReady (\r
371 IN EFI_EVENT Event,\r
e7108d0e 372 IN VOID *Context\r
f6755908
OM
373 )\r
374{\r
375 UINTN Size;\r
e7108d0e 376 VOID *Data;\r
f6755908
OM
377 EFI_STATUS Status;\r
378\r
379 do {\r
380 Status = mTransport->Receive (&Size, &Data);\r
381 if (!EFI_ERROR (Status)) {\r
382 if (mState == ExpectCmdState) {\r
e7108d0e 383 AcceptCmd (Size, (CHAR8 *)Data);\r
f6755908
OM
384 } else if (mState == ExpectDataState) {\r
385 AcceptData (Size, Data);\r
386 } else {\r
387 ASSERT (FALSE);\r
388 }\r
e7108d0e 389\r
f6755908
OM
390 FreePool (Data);\r
391 }\r
392 } while (!EFI_ERROR (Status));\r
393\r
394 // Quit if there was a fatal error\r
395 if (Status != EFI_NOT_READY) {\r
396 ASSERT (Status == EFI_DEVICE_ERROR);\r
397 // (Put a newline at the beginning as we are probably in the data phase,\r
398 // so the download progress line, with no '\n' is probably on the console)\r
399 mTextOut->OutputString (mTextOut, L"\r\nFatal error receiving data. Exiting.\r\n");\r
400 gBS->SignalEvent (mFinishedEvent);\r
401 }\r
402}\r
403\r
404/*\r
405 Event notify for a fatal error in transmission.\r
406*/\r
407STATIC\r
408VOID\r
409FatalErrorNotify (\r
410 IN EFI_EVENT Event,\r
e7108d0e 411 IN VOID *Context\r
f6755908
OM
412 )\r
413{\r
414 mTextOut->OutputString (mTextOut, L"Fatal error sending command response. Exiting.\r\n");\r
415 gBS->SignalEvent (mFinishedEvent);\r
416}\r
417\r
418EFI_STATUS\r
419EFIAPI\r
420FastbootAppEntryPoint (\r
e7108d0e
MK
421 IN EFI_HANDLE ImageHandle,\r
422 IN EFI_SYSTEM_TABLE *SystemTable\r
f6755908
OM
423 )\r
424{\r
425 EFI_STATUS Status;\r
426 EFI_EVENT ReceiveEvent;\r
427 EFI_EVENT WaitEventArray[2];\r
428 UINTN EventIndex;\r
e7108d0e 429 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
68617659 430 EFI_INPUT_KEY Key;\r
f6755908
OM
431\r
432 mDataBuffer = NULL;\r
433\r
434 Status = gBS->LocateProtocol (\r
e7108d0e
MK
435 &gAndroidFastbootTransportProtocolGuid,\r
436 NULL,\r
437 (VOID **)&mTransport\r
438 );\r
f6755908 439 if (EFI_ERROR (Status)) {\r
a1878955 440 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't open Fastboot Transport Protocol: %r\n", Status));\r
f6755908
OM
441 return Status;\r
442 }\r
443\r
e7108d0e 444 Status = gBS->LocateProtocol (&gAndroidFastbootPlatformProtocolGuid, NULL, (VOID **)&mPlatform);\r
f6755908 445 if (EFI_ERROR (Status)) {\r
a1878955 446 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't open Fastboot Platform Protocol: %r\n", Status));\r
f6755908
OM
447 return Status;\r
448 }\r
449\r
450 Status = mPlatform->Init ();\r
451 if (EFI_ERROR (Status)) {\r
a1878955 452 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't initialise Fastboot Platform Protocol: %r\n", Status));\r
f6755908
OM
453 return Status;\r
454 }\r
455\r
e7108d0e 456 Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **)&mTextOut);\r
f6755908 457 if (EFI_ERROR (Status)) {\r
e7108d0e
MK
458 DEBUG ((\r
459 DEBUG_ERROR,\r
460 "Fastboot: Couldn't open Text Output Protocol: %r\n",\r
461 Status\r
f6755908
OM
462 ));\r
463 return Status;\r
464 }\r
465\r
e7108d0e 466 Status = gBS->LocateProtocol (&gEfiSimpleTextInProtocolGuid, NULL, (VOID **)&TextIn);\r
f6755908 467 if (EFI_ERROR (Status)) {\r
a1878955 468 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't open Text Input Protocol: %r\n", Status));\r
f6755908
OM
469 return Status;\r
470 }\r
471\r
472 // Disable watchdog\r
473 Status = gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);\r
474 if (EFI_ERROR (Status)) {\r
a1878955 475 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't disable watchdog timer: %r\n", Status));\r
f6755908
OM
476 }\r
477\r
478 // Create event for receipt of data from the host\r
479 Status = gBS->CreateEvent (\r
480 EVT_NOTIFY_SIGNAL,\r
481 TPL_CALLBACK,\r
482 DataReady,\r
483 NULL,\r
484 &ReceiveEvent\r
485 );\r
486 ASSERT_EFI_ERROR (Status);\r
487\r
488 // Create event for exiting application when "continue" command is received\r
489 Status = gBS->CreateEvent (0, TPL_CALLBACK, NULL, NULL, &mFinishedEvent);\r
490 ASSERT_EFI_ERROR (Status);\r
491\r
492 // Create event to pass to FASTBOOT_TRANSPORT_PROTOCOL.Send, signalling a\r
493 // fatal error\r
494 Status = gBS->CreateEvent (\r
e7108d0e
MK
495 EVT_NOTIFY_SIGNAL,\r
496 TPL_CALLBACK,\r
497 FatalErrorNotify,\r
498 NULL,\r
499 &mFatalSendErrorEvent\r
500 );\r
f6755908
OM
501 ASSERT_EFI_ERROR (Status);\r
502\r
f6755908
OM
503 // Start listening for data\r
504 Status = mTransport->Start (\r
e7108d0e
MK
505 ReceiveEvent\r
506 );\r
f6755908 507 if (EFI_ERROR (Status)) {\r
a1878955 508 DEBUG ((DEBUG_ERROR, "Fastboot: Couldn't start transport: %r\n", Status));\r
f6755908
OM
509 return Status;\r
510 }\r
511\r
512 // Talk to the user\r
e7108d0e
MK
513 mTextOut->OutputString (\r
514 mTextOut,\r
515 L"Android Fastboot mode - version " ANDROID_FASTBOOT_VERSION ". Press RETURN or SPACE key to quit.\r\n"\r
516 );\r
f6755908
OM
517\r
518 // Quit when the user presses any key, or mFinishedEvent is signalled\r
519 WaitEventArray[0] = mFinishedEvent;\r
520 WaitEventArray[1] = TextIn->WaitForKey;\r
68617659
HZ
521 while (1) {\r
522 gBS->WaitForEvent (2, WaitEventArray, &EventIndex);\r
523 Status = TextIn->ReadKeyStroke (gST->ConIn, &Key);\r
524 if (Key.ScanCode == SCAN_NULL) {\r
525 if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN) ||\r
e7108d0e
MK
526 (Key.UnicodeChar == L' '))\r
527 {\r
68617659
HZ
528 break;\r
529 }\r
530 }\r
531 }\r
f6755908
OM
532\r
533 mTransport->Stop ();\r
534 if (EFI_ERROR (Status)) {\r
a1878955 535 DEBUG ((DEBUG_ERROR, "Warning: Fastboot Transport Stop: %r\n", Status));\r
f6755908 536 }\r
e7108d0e 537\r
f6755908
OM
538 mPlatform->UnInit ();\r
539\r
540 return EFI_SUCCESS;\r
541}\r