]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
ArmPkg/CompilerIntrinsicsLib: Add uread, uwrite GCC assembly sources
[mirror_edk2.git] / Vlv2TbltDevicePkg / Application / FirmwareUpdate / FirmwareUpdate.c
CommitLineData
3cbfba02
DW
1/** @file\r
2\r
9ea2d901 3Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
3cbfba02 4 \r\r
9dc8036d
MK
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
3cbfba02
DW
7 \r\r
8\r
9**/\r
10\r
11#include "FirmwareUpdate.h"\r
12\r
13EFI_HII_HANDLE HiiHandle;\r
14\r
15//\r
16// MinnowMax Flash Layout\r
17//\r
18//Start (hex) End (hex) Length (hex) Area Name\r
19//----------- --------- ------------ ---------\r
20//00000000 007FFFFF 00800000 Flash Image\r
21//\r
22//00000000 00000FFF 00001000 Descriptor Region\r
9ea2d901
SL
23//00001000 003FFFFF 003FF000 TXE Region\r
24//00500000 007FFFFF 00400000 BIOS Region\r
3cbfba02
DW
25//\r
26FV_REGION_INFO mRegionInfo[] = {\r
27 {FixedPcdGet32 (PcdFlashDescriptorBase), FixedPcdGet32 (PcdFlashDescriptorSize), TRUE},\r
28 {FixedPcdGet32 (PcdTxeRomBase), FixedPcdGet32 (PcdTxeRomSize), TRUE},\r
29 {FixedPcdGet32 (PcdBiosRomBase), FixedPcdGet32 (PcdBiosRomSize), TRUE}\r
30};\r
31\r
849a7063 32UINTN mRegionInfoCount = ARRAY_SIZE (mRegionInfo);\r
3cbfba02
DW
33\r
34FV_INPUT_DATA mInputData = {0};\r
35\r
36EFI_SPI_PROTOCOL *mSpiProtocol;\r
37\r
38EFI_STATUS\r
39GetRegionIndex (\r
40 IN EFI_PHYSICAL_ADDRESS Address,\r
41 OUT UINTN *RegionIndex\r
42 )\r
43{\r
44 UINTN Index;\r
45\r
46 for (Index = 0; Index < mRegionInfoCount; Index++) {\r
47 if (Address >= mRegionInfo[Index].Base &&\r
48 Address < (mRegionInfo[Index].Base + mRegionInfo[Index].Size)\r
49 ) {\r
50 break;\r
51 }\r
52 }\r
53\r
54 *RegionIndex = Index;\r
55 if (Index >= mRegionInfoCount) {\r
56 return EFI_NOT_FOUND;\r
57 }\r
58 return EFI_SUCCESS;\r
59}\r
60\r
61BOOLEAN\r
62UpdateBlock (\r
63 IN EFI_PHYSICAL_ADDRESS Address\r
64 )\r
65{\r
66 EFI_STATUS Status;\r
67 UINTN Index;\r
68\r
69 if (mInputData.FullFlashUpdate) {\r
70 return TRUE;\r
71 }\r
72\r
73 Status = GetRegionIndex (Address, &Index);\r
74 if ((!EFI_ERROR(Status)) && mRegionInfo[Index].Update) {\r
75 return TRUE;\r
76 }\r
77\r
78 return FALSE;\r
79}\r
80\r
81EFI_STATUS\r
82MarkRegionState (\r
83 IN EFI_PHYSICAL_ADDRESS Address,\r
84 IN BOOLEAN Update\r
85 )\r
86{\r
87 EFI_STATUS Status;\r
88 UINTN Index;\r
89\r
90 Status = GetRegionIndex (Address, &Index);\r
91 if (!EFI_ERROR(Status)) {\r
92 mRegionInfo[Index].Update = Update;\r
93 }\r
94\r
95 return Status;\r
96}\r
97\r
98UINTN\r
99InternalPrintToken (\r
100 IN CONST CHAR16 *Format,\r
101 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Console,\r
102 IN VA_LIST Marker\r
103 )\r
104{\r
105 EFI_STATUS Status;\r
106 UINTN Return;\r
107 CHAR16 *Buffer;\r
108 UINTN BufferSize;\r
109\r
110 ASSERT (Format != NULL);\r
111 ASSERT (((UINTN) Format & BIT0) == 0);\r
112 ASSERT (Console != NULL);\r
113\r
114 BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);\r
115\r
116 Buffer = (CHAR16 *) AllocatePool(BufferSize);\r
117 ASSERT (Buffer != NULL);\r
118\r
119 Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);\r
120\r
121 if (Console != NULL && Return > 0) {\r
122 //\r
123 // To be extra safe make sure Console has been initialized.\r
124 //\r
125 Status = Console->OutputString (Console, Buffer);\r
126 if (EFI_ERROR (Status)) {\r
127 Return = 0;\r
128 }\r
129 }\r
130\r
131 FreePool (Buffer);\r
132\r
133 return Return;\r
134}\r
135\r
136UINTN\r
137EFIAPI\r
138PrintToken (\r
139 IN UINT16 Token,\r
140 IN EFI_HII_HANDLE Handle,\r
141 ...\r
142 )\r
143{\r
144 VA_LIST Marker;\r
145 UINTN Return;\r
146 CHAR16 *Format;\r
147\r
148 VA_START (Marker, Handle);\r
149\r
150 Format = HiiGetString (Handle, Token, NULL);\r
151 ASSERT (Format != NULL);\r
152\r
153 Return = InternalPrintToken (Format, gST->ConOut, Marker);\r
154\r
155 FreePool (Format);\r
156\r
157 VA_END (Marker);\r
158\r
159 return Return;\r
160}\r
161\r
162EFI_STATUS\r
163ParseCommandLine (\r
164 IN UINTN Argc,\r
165 IN CHAR16 **Argv\r
166 )\r
167{\r
168 EFI_STATUS Status;\r
169 UINTN Index;\r
170\r
171 //\r
172 // Check to make sure that the command line has enough arguments for minimal\r
173 // operation. The minimum is just the file name.\r
174 //\r
175 if (Argc < 2 || Argc > 4) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178\r
179 //\r
180 // Loop through command line arguments.\r
181 //\r
182 for (Index = 1; Index < Argc; Index++) {\r
183 //\r
184 // Make sure the string is valid.\r
185 //\r
186 if (StrLen (Argv[Index]) == 0) {;\r
187 PrintToken (STRING_TOKEN (STR_FWUPDATE_ZEROLENGTH_ARG), HiiHandle);\r
188 return EFI_INVALID_PARAMETER;\r
189 }\r
190\r
191 //\r
192 // Check to see if this is an option or the file name.\r
193 //\r
194 if ((Argv[Index])[0] == L'-' || (Argv[Index])[0] == L'/') {\r
195 //\r
196 // Parse the arguments.\r
197 //\r
198 if ((StrCmp (Argv[Index], L"-h") == 0) ||\r
199 (StrCmp (Argv[Index], L"--help") == 0) ||\r
200 (StrCmp (Argv[Index], L"/?") == 0) ||\r
201 (StrCmp (Argv[Index], L"/h") == 0)) {\r
202 //\r
203 // Print Help Information.\r
204 //\r
205 return EFI_INVALID_PARAMETER;\r
206 } else if (StrCmp (Argv[Index], L"-m") == 0) {\r
207 //\r
208 // Parse the MAC address here.\r
209 //\r
210 Status = ConvertMac(Argv[Index+1]);\r
211 if (EFI_ERROR(Status)) {\r
212 PrintToken (STRING_TOKEN (STR_FWUPDATE_INVAILD_MAC), HiiHandle);\r
213 return Status;\r
214 }\r
215\r
216 //\r
217 // Save the MAC address to mInputData.MacValue.\r
218 //\r
219 mInputData.UpdateMac= TRUE;\r
220 Index++;\r
221 } else {\r
222 //\r
223 // Invalid option was provided.\r
224 //\r
225 return EFI_INVALID_PARAMETER;\r
226 }\r
227 }\r
228 if ((Index == Argc - 1) && (StrCmp (Argv[Index - 1], L"-m") != 0)) {\r
229 //\r
230 // The only parameter that is not an option is the firmware image. Check\r
231 // to make sure that the file exists.\r
232 //\r
233 Status = ShellIsFile (Argv[Index]);\r
234 if (EFI_ERROR (Status)) {\r
235 PrintToken (STRING_TOKEN (STR_FWUPDATE_FILE_NOT_FOUND_ERROR), HiiHandle, Argv[Index]);\r
236 return EFI_INVALID_PARAMETER;\r
237 }\r
238 if (StrLen (Argv[Index]) > INPUT_STRING_LEN) {\r
239 PrintToken (STRING_TOKEN (STR_FWUPDATE_PATH_ERROR), HiiHandle, Argv[Index]);\r
240 return EFI_INVALID_PARAMETER;\r
241 }\r
242 StrCpy (mInputData.FileName, Argv[Index]);\r
243 mInputData.UpdateFromFile = TRUE;\r
244 }\r
245 }\r
246\r
247 return EFI_SUCCESS;\r
248}\r
249\r
250INTN\r
251EFIAPI\r
252ShellAppMain (\r
253 IN UINTN Argc,\r
254 IN CHAR16 **Argv\r
255 )\r
256{\r
257 EFI_STATUS Status;\r
258 UINTN Index;\r
259 UINT32 FileSize;\r
260 UINT32 BufferSize;\r
261 UINT8 *FileBuffer;\r
262 UINT8 *Buffer;\r
263 EFI_PHYSICAL_ADDRESS Address;\r
264 UINTN CountOfBlocks;\r
265 EFI_TPL OldTpl;\r
266 BOOLEAN ResetRequired;\r
267 BOOLEAN FlashError;\r
268\r
269 Index = 0;\r
270 FileSize = 0;\r
271 BufferSize = 0;\r
272 FileBuffer = NULL;\r
273 Buffer = NULL;\r
274 Address = 0;\r
275 CountOfBlocks = 0;\r
276 ResetRequired = FALSE;\r
277 FlashError = FALSE;\r
278\r
279 Status = EFI_SUCCESS;\r
280\r
281 mInputData.FullFlashUpdate = TRUE;\r
282\r
283 //\r
284 // Publish our HII data.\r
285 //\r
286 HiiHandle = HiiAddPackages (\r
287 &gEfiCallerIdGuid,\r
288 NULL,\r
289 FirmwareUpdateStrings,\r
290 NULL\r
291 );\r
292 if (HiiHandle == NULL) {\r
293 Status = EFI_OUT_OF_RESOURCES;\r
294 goto Done;\r
295 }\r
296\r
297 //\r
298 // Locate the SPI protocol.\r
299 //\r
300 Status = gBS->LocateProtocol (\r
301 &gEfiSpiProtocolGuid,\r
302 NULL,\r
303 (VOID **)&mSpiProtocol\r
304 );\r
305 if (EFI_ERROR (Status)) {\r
306 PrintToken (STRING_TOKEN (STR_SPI_NOT_FOUND), HiiHandle);\r
307 return EFI_DEVICE_ERROR;\r
308 }\r
309\r
310 //\r
311 // Parse the command line.\r
312 //\r
313 Status = ParseCommandLine (Argc, Argv);\r
314 if (EFI_ERROR (Status)) {\r
315 PrintHelpInfo ();\r
316 Status = EFI_SUCCESS;\r
317 goto Done;\r
318 }\r
319\r
320 //\r
321 // Display sign-on information.\r
322 //\r
323 PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);\r
324 PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);\r
325 PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);\r
326\r
327 //\r
328 // Test to see if the firmware needs to be updated.\r
329 //\r
330 if (mInputData.UpdateFromFile) {\r
331 //\r
332 // Get the file to use in the update.\r
333 //\r
334 PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE), HiiHandle, mInputData.FileName);\r
335 Status = ReadFileData (mInputData.FileName, &FileBuffer, &FileSize);\r
336 if (EFI_ERROR (Status)) {\r
337 PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE_ERROR), HiiHandle, mInputData.FileName);\r
338 goto Done;\r
339 }\r
340\r
341 //\r
342 // Check that the file and flash sizes match.\r
343 //\r
344 if (FileSize != PcdGet32 (PcdFlashChipSize)) {\r
345 PrintToken (STRING_TOKEN (STR_FWUPDATE_SIZE), HiiHandle);\r
346 Status = EFI_UNSUPPORTED;\r
347 goto Done;\r
348 }\r
349\r
350 //\r
351 // Display flash update information.\r
352 //\r
353 PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATING_FIRMWARE), HiiHandle);\r
354\r
355 //\r
356 // Update it.\r
357 //\r
358 Buffer = FileBuffer;\r
359 BufferSize = FileSize;\r
360 Address = PcdGet32 (PcdFlashChipBase);\r
361 CountOfBlocks = (UINTN) (BufferSize / BLOCK_SIZE);\r
362\r
363 //\r
364 // Raise TPL to TPL_NOTIFY to block any event handler,\r
365 // while still allowing RaiseTPL(TPL_NOTIFY) within\r
366 // output driver during Print().\r
367 //\r
368 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
369 for (Index = 0; Index < CountOfBlocks; Index++) {\r
370 //\r
371 // Handle block based on address and contents.\r
372 //\r
373 if (!UpdateBlock (Address)) {\r
374 DEBUG((EFI_D_INFO, "Skipping block at 0x%lx\n", Address));\r
375 } else if (!EFI_ERROR (InternalCompareBlock (Address, Buffer))) {\r
376 DEBUG((EFI_D_INFO, "Skipping block at 0x%lx (already programmed)\n", Address));\r
377 } else {\r
378 //\r
379 // Display a dot for each block being updated.\r
380 //\r
381 Print (L".");\r
382\r
383 //\r
384 // Flag that the flash image will be changed and the system must be rebooted\r
385 // to use the change.\r
386 //\r
387 ResetRequired = TRUE;\r
388\r
389 //\r
390 // Make updating process uninterruptable,\r
391 // so that the flash memory area is not accessed by other entities\r
392 // which may interfere with the updating process.\r
393 //\r
394 Status = InternalEraseBlock (Address);\r
395 ASSERT_EFI_ERROR(Status);\r
396 if (EFI_ERROR (Status)) {\r
397 gBS->RestoreTPL (OldTpl);\r
398 FlashError = TRUE;\r
399 goto Done;\r
400 }\r
401 Status = InternalWriteBlock (\r
402 Address,\r
403 Buffer,\r
404 (BufferSize > BLOCK_SIZE ? BLOCK_SIZE : BufferSize)\r
405 );\r
406 if (EFI_ERROR (Status)) {\r
407 gBS->RestoreTPL (OldTpl);\r
408 FlashError = TRUE;\r
409 goto Done;\r
410 }\r
411 }\r
412\r
413 //\r
414 // Move to next block to update.\r
415 //\r
416 Address += BLOCK_SIZE;\r
417 Buffer += BLOCK_SIZE;\r
418 if (BufferSize > BLOCK_SIZE) {\r
419 BufferSize -= BLOCK_SIZE;\r
420 } else {\r
421 BufferSize = 0;\r
422 }\r
423 }\r
424 gBS->RestoreTPL (OldTpl);\r
425\r
426 //\r
427 // Print result of update.\r
428 //\r
429 if (!FlashError) {\r
430 if (ResetRequired) {\r
431 Print (L"\n");\r
432 PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_SUCCESS), HiiHandle);\r
433 } else {\r
434 PrintToken (STRING_TOKEN (STR_FWUPDATE_NO_RESET), HiiHandle);\r
435 }\r
436 } else {\r
437 goto Done;\r
438 }\r
439 }\r
440\r
441 //\r
442 // All flash updates are done so see if the system needs to be reset.\r
443 //\r
444 if (ResetRequired && !FlashError) {\r
445 //\r
446 // Update successful.\r
447 //\r
448 for (Index = 5; Index > 0; Index--) {\r
449 PrintToken (STRING_TOKEN (STR_FWUPDATE_SHUTDOWN), HiiHandle, Index);\r
450 gBS->Stall (1000000);\r
451 }\r
452\r
453 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
454 PrintToken (STRING_TOKEN (STR_FWUPDATE_MANUAL_RESET), HiiHandle);\r
455 CpuDeadLoop ();\r
456 }\r
457\r
458Done:\r
459 //\r
460 // Print flash update failure message if error detected.\r
461 //\r
462 if (FlashError) {\r
463 PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_FAILED), HiiHandle, Index);\r
464 }\r
465\r
466 //\r
467 // Do cleanup.\r
468 //\r
469 if (HiiHandle != NULL) {\r
470 HiiRemovePackages (HiiHandle);\r
471 }\r
472 if (FileBuffer) {\r
473 gBS->FreePool (FileBuffer);\r
474 }\r
475\r
476 return Status;\r
477}\r
478\r
479STATIC\r
480EFI_STATUS\r
481InternalEraseBlock (\r
482 IN EFI_PHYSICAL_ADDRESS BaseAddress\r
483 )\r
484/*++\r
485\r
486Routine Description:\r
487\r
488 Erase the whole block.\r
489\r
490Arguments:\r
491\r
492 BaseAddress - Base address of the block to be erased.\r
493\r
494Returns:\r
495\r
496 EFI_SUCCESS - The command completed successfully.\r
497 Other - Device error or wirte-locked, operation failed.\r
498\r
499--*/\r
500{\r
501 EFI_STATUS Status;\r
502 UINTN NumBytes;\r
503\r
504 NumBytes = BLOCK_SIZE;\r
505\r
506 Status = SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes);\r
507\r
508 return Status;\r
509}\r
510\r
511#if 0\r
512STATIC\r
513EFI_STATUS\r
514InternalReadBlock (\r
515 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
516 OUT VOID *ReadBuffer\r
517 )\r
518{\r
519 EFI_STATUS Status;\r
520 UINT32 BlockSize;\r
521\r
522 BlockSize = BLOCK_SIZE;\r
523\r
524 Status = SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer);\r
525\r
526 return Status;\r
527}\r
528#endif\r
529\r
530STATIC\r
531EFI_STATUS\r
532InternalCompareBlock (\r
533 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
534 IN UINT8 *Buffer\r
535 )\r
536{\r
537 EFI_STATUS Status;\r
538 VOID *CompareBuffer;\r
539 UINT32 NumBytes;\r
540 INTN CompareResult;\r
541\r
542 NumBytes = BLOCK_SIZE;\r
543 CompareBuffer = AllocatePool (NumBytes);\r
544 if (CompareBuffer == NULL) {\r
545 Status = EFI_OUT_OF_RESOURCES;\r
546 goto Done;\r
547 }\r
548\r
549 Status = SpiFlashRead ((UINTN) BaseAddress, &NumBytes, CompareBuffer);\r
550 if (EFI_ERROR (Status)) {\r
551 goto Done;\r
552 }\r
553 CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE);\r
554 if (CompareResult != 0) {\r
555 Status = EFI_VOLUME_CORRUPTED;\r
556 }\r
557\r
558Done:\r
559 if (CompareBuffer != NULL) {\r
560 FreePool (CompareBuffer);\r
561 }\r
562\r
563 return Status;\r
564}\r
565\r
566STATIC\r
567EFI_STATUS\r
568InternalWriteBlock (\r
569 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
570 IN UINT8 *Buffer,\r
571 IN UINT32 BufferSize\r
572 )\r
573/*++\r
574\r
575Routine Description:\r
576\r
577 Write a block of data.\r
578\r
579Arguments:\r
580\r
581 BaseAddress - Base address of the block.\r
582 Buffer - Data buffer.\r
583 BufferSize - Size of the buffer.\r
584\r
585Returns:\r
586\r
587 EFI_SUCCESS - The command completed successfully.\r
588 EFI_INVALID_PARAMETER - Invalid parameter, can not proceed.\r
589 Other - Device error or wirte-locked, operation failed.\r
590\r
591--*/\r
592{\r
593 EFI_STATUS Status;\r
594\r
595 Status = SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer);\r
596 ASSERT_EFI_ERROR(Status);\r
597 if (EFI_ERROR (Status)) {\r
598 DEBUG((EFI_D_ERROR, "\nFlash write error."));\r
599 return Status;\r
600 }\r
601\r
602 WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress, BLOCK_SIZE);\r
603\r
604 Status = InternalCompareBlock (BaseAddress, Buffer);\r
605 if (EFI_ERROR (Status)) {\r
606 DEBUG((EFI_D_ERROR, "\nError when writing to BaseAddress %lx with different at offset %x.", BaseAddress, Status));\r
607 } else {\r
608 DEBUG((EFI_D_INFO, "\nVerified data written to Block at %lx is correct.", BaseAddress));\r
609 }\r
610\r
611 return Status;\r
612\r
613}\r
614\r
615STATIC\r
616EFI_STATUS\r
617ReadFileData (\r
618 IN CHAR16 *FileName,\r
619 OUT UINT8 **Buffer,\r
620 OUT UINT32 *BufferSize\r
621 )\r
622{\r
623 EFI_STATUS Status;\r
624 SHELL_FILE_HANDLE FileHandle;\r
625 UINT64 Size;\r
626 VOID *NewBuffer;\r
627 UINTN ReadSize;\r
628\r
629 FileHandle = NULL;\r
630 NewBuffer = NULL;\r
631 Size = 0;\r
632\r
633 Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
634 if (EFI_ERROR (Status)) {\r
635 goto Done;\r
636 }\r
637\r
638 Status = FileHandleIsDirectory (FileHandle);\r
639 if (!EFI_ERROR (Status)) {\r
640 Status = EFI_NOT_FOUND;\r
641 goto Done;\r
642 }\r
643\r
644 Status = FileHandleGetSize (FileHandle, &Size);\r
645 if (EFI_ERROR (Status)) {\r
646 goto Done;\r
647 }\r
648\r
649 NewBuffer = AllocatePool ((UINTN) Size);\r
650\r
651 ReadSize = (UINTN) Size;\r
652 Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);\r
653 if (EFI_ERROR (Status)) {\r
654 goto Done;\r
655 } else if (ReadSize != (UINTN) Size) {\r
656 Status = EFI_INVALID_PARAMETER;\r
657 goto Done;\r
658 }\r
659\r
660Done:\r
661 if (FileHandle != NULL) {\r
662 ShellCloseFile (&FileHandle);\r
663 }\r
664\r
665 if (EFI_ERROR (Status)) {\r
666 if (NewBuffer != NULL) {\r
667 FreePool (NewBuffer);\r
668 }\r
669 } else {\r
670 *Buffer = NewBuffer;\r
671 *BufferSize = (UINT32) Size;\r
672 }\r
673\r
674 return Status;\r
675}\r
676\r
677STATIC\r
678VOID\r
679PrintHelpInfo (\r
680 VOID\r
681 )\r
682/*++\r
683\r
684Routine Description:\r
685\r
686 Print out help information.\r
687\r
688Arguments:\r
689\r
690 None.\r
691\r
692Returns:\r
693\r
694 None.\r
695\r
696--*/\r
697{\r
698 PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);\r
699 PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);\r
700 PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);\r
701\r
702 Print (L"\n");\r
703 PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE), HiiHandle);\r
704 PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_1), HiiHandle);\r
705 PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_2), HiiHandle);\r
706 PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_3), HiiHandle);\r
707 PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_4), HiiHandle);\r
708\r
709 Print (L"\n");\r
710}\r
711\r
712/**\r
713 Read NumBytes bytes of data from the address specified by\r
714 PAddress into Buffer.\r
715\r
716 @param[in] Address The starting physical address of the read.\r
717 @param[in,out] NumBytes On input, the number of bytes to read. On output, the number\r
718 of bytes actually read.\r
719 @param[out] Buffer The destination data buffer for the read.\r
720\r
721 @retval EFI_SUCCESS Opertion is successful.\r
722 @retval EFI_DEVICE_ERROR If there is any device errors.\r
723\r
724**/\r
725EFI_STATUS\r
726EFIAPI\r
727SpiFlashRead (\r
728 IN UINTN Address,\r
729 IN OUT UINT32 *NumBytes,\r
730 OUT UINT8 *Buffer\r
731 )\r
732{\r
733 EFI_STATUS Status = EFI_SUCCESS;\r
734 UINTN Offset = 0;\r
735\r
736 ASSERT ((NumBytes != NULL) && (Buffer != NULL));\r
737\r
738 Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);\r
739\r
740 Status = mSpiProtocol->Execute (\r
741 mSpiProtocol,\r
742 1, //SPI_READ,\r
743 0, //SPI_WREN,\r
744 TRUE,\r
745 TRUE,\r
746 FALSE,\r
747 Offset,\r
748 BLOCK_SIZE,\r
749 Buffer,\r
750 EnumSpiRegionAll\r
751 );\r
752 return Status;\r
753\r
754}\r
755\r
756/**\r
757 Write NumBytes bytes of data from Buffer to the address specified by\r
758 PAddresss.\r
759\r
760 @param[in] Address The starting physical address of the write.\r
761 @param[in,out] NumBytes On input, the number of bytes to write. On output,\r
762 the actual number of bytes written.\r
763 @param[in] Buffer The source data buffer for the write.\r
764\r
765 @retval EFI_SUCCESS Opertion is successful.\r
766 @retval EFI_DEVICE_ERROR If there is any device errors.\r
767\r
768**/\r
769EFI_STATUS\r
770EFIAPI\r
771SpiFlashWrite (\r
772 IN UINTN Address,\r
773 IN OUT UINT32 *NumBytes,\r
774 IN UINT8 *Buffer\r
775 )\r
776{\r
777 EFI_STATUS Status;\r
778 UINTN Offset;\r
779 UINT32 Length;\r
780 UINT32 RemainingBytes;\r
781\r
782 ASSERT ((NumBytes != NULL) && (Buffer != NULL));\r
783 ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));\r
784\r
785 Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);\r
786\r
787 ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));\r
788\r
789 Status = EFI_SUCCESS;\r
790 RemainingBytes = *NumBytes;\r
791\r
792 while (RemainingBytes > 0) {\r
793 if (RemainingBytes > SIZE_4KB) {\r
794 Length = SIZE_4KB;\r
795 } else {\r
796 Length = RemainingBytes;\r
797 }\r
798 Status = mSpiProtocol->Execute (\r
799 mSpiProtocol,\r
800 SPI_PROG,\r
801 SPI_WREN,\r
802 TRUE,\r
803 TRUE,\r
804 TRUE,\r
805 (UINT32) Offset,\r
806 Length,\r
807 Buffer,\r
808 EnumSpiRegionAll\r
809 );\r
810 if (EFI_ERROR (Status)) {\r
811 break;\r
812 }\r
813 RemainingBytes -= Length;\r
814 Offset += Length;\r
815 Buffer += Length;\r
816 }\r
817\r
818 //\r
819 // Actual number of bytes written.\r
820 //\r
821 *NumBytes -= RemainingBytes;\r
822\r
823 return Status;\r
824}\r
825\r
826/**\r
827 Erase the block starting at Address.\r
828\r
829 @param[in] Address The starting physical address of the block to be erased.\r
830 This library assume that caller garantee that the PAddress\r
831 is at the starting address of this block.\r
832 @param[in] NumBytes On input, the number of bytes of the logical block to be erased.\r
833 On output, the actual number of bytes erased.\r
834\r
835 @retval EFI_SUCCESS. Opertion is successful.\r
836 @retval EFI_DEVICE_ERROR If there is any device errors.\r
837\r
838**/\r
839EFI_STATUS\r
840EFIAPI\r
841SpiFlashBlockErase (\r
842 IN UINTN Address,\r
843 IN UINTN *NumBytes\r
844 )\r
845{\r
846 EFI_STATUS Status;\r
847 UINTN Offset;\r
848 UINTN RemainingBytes;\r
849\r
850 ASSERT (NumBytes != NULL);\r
851 ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));\r
852\r
853 Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);\r
854\r
855 ASSERT ((*NumBytes % SIZE_4KB) == 0);\r
856 ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));\r
857\r
858 Status = EFI_SUCCESS;\r
859 RemainingBytes = *NumBytes;\r
860\r
861 while (RemainingBytes > 0) {\r
862 Status = mSpiProtocol->Execute (\r
863 mSpiProtocol,\r
864 SPI_SERASE,\r
865 SPI_WREN,\r
866 FALSE,\r
867 TRUE,\r
868 FALSE,\r
869 (UINT32) Offset,\r
870 0,\r
871 NULL,\r
872 EnumSpiRegionAll\r
873 );\r
874 if (EFI_ERROR (Status)) {\r
875 break;\r
876 }\r
877 RemainingBytes -= SIZE_4KB;\r
878 Offset += SIZE_4KB;\r
879 }\r
880\r
881 //\r
882 // Actual number of bytes erased.\r
883 //\r
884 *NumBytes -= RemainingBytes;\r
885\r
886 return Status;\r
887}\r
888\r
889EFI_STATUS\r
890EFIAPI\r
891ConvertMac (\r
892 CHAR16 *Str\r
893 )\r
894{\r
895 UINTN Index;\r
896 UINT8 Temp[MAC_ADD_STR_LEN];\r
897\r
898 if (Str == NULL)\r
899 return EFI_INVALID_PARAMETER;\r
900\r
901 if (StrLen(Str) != MAC_ADD_STR_LEN)\r
902 return EFI_INVALID_PARAMETER;\r
903\r
904 for (Index = 0; Index < MAC_ADD_STR_LEN; Index++) {\r
905 if (Str[Index] >= 0x30 && Str[Index] <= 0x39) {\r
906 Temp[Index] = (UINT8)Str[Index] - 0x30;\r
907 } else if (Str[Index] >= 0x41 && Str[Index] <= 0x46) {\r
908 Temp[Index] = (UINT8)Str[Index] - 0x37;\r
909 } else if (Str[Index] >= 0x61 && Str[Index] <= 0x66) {\r
910 Temp[Index] = (UINT8)Str[Index] - 0x57;\r
911 } else {\r
912 return EFI_INVALID_PARAMETER;\r
913 }\r
914 }\r
915\r
916 for (Index = 0; Index < MAC_ADD_BYTE_COUNT; Index++) {\r
917 mInputData.MacValue[Index] = (Temp[2 * Index] << 4) + Temp[2 * Index + 1];\r
918 }\r
919\r
920 return EFI_SUCCESS;\r
921}\r
922\r