]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Print.c
MdeModulePkg PciBusDxe: Add typecast to eliminate possible "loss of precision" warning.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Print.c
15
16 Abstract:
17
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
20
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
23
24 VSPrint, Print, SPrint format specification has the follwoing form
25
26 %[flags][width]type
27
28 flags:
29 '-' - Left justify
30 '+' - Prefix a sign
31 ' ' - Prefix a blank
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
34 'l' - UINT64
35 'L' - UINT64
36
37 width:
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
40
41 type:
42 'X' - argument is a UINTN hex number, prefix '0'
43 'x' - argument is a hex number
44 'd' - argument is a decimal number
45 'a' - argument is an ascii string
46 'S','s' - argument is an Unicode string
47 'g' - argument is a pointer to an EFI_GUID
48 't' - argument is a pointer to an EFI_TIME structure
49 'c' - argument is an ascii character
50 'r' - argument is EFI_STATUS
51 '%' - Print a %
52
53 --*/
54
55 #include "Tiano.h"
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
61 #include "Print.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
64 #else
65 #include EFI_PROTOCOL_DEFINITION (Hii)
66 #endif
67
68
69 STATIC
70 UINTN
71 GuidToString (
72 IN EFI_GUID *Guid,
73 IN OUT CHAR_W *Buffer,
74 IN UINTN BufferSize
75 );
76
77 STATIC
78 UINTN
79 TimeToString (
80 IN EFI_TIME *Time,
81 IN OUT CHAR_W *Buffer,
82 IN UINTN BufferSize
83 );
84
85 STATIC
86 UINTN
87 EfiStatusToString (
88 IN EFI_STATUS Status,
89 OUT CHAR_W *Buffer,
90 IN UINTN BufferSize
91 );
92
93 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {
94 {0x00, 0x00, 0x00, 0x00},
95 {0x98, 0x00, 0x00, 0x00},
96 {0x00, 0x98, 0x00, 0x00},
97 {0x98, 0x98, 0x00, 0x00},
98 {0x00, 0x00, 0x98, 0x00},
99 {0x98, 0x00, 0x98, 0x00},
100 {0x00, 0x98, 0x98, 0x00},
101 {0x98, 0x98, 0x98, 0x00},
102 {0x10, 0x10, 0x10, 0x00},
103 {0xff, 0x10, 0x10, 0x00},
104 {0x10, 0xff, 0x10, 0x00},
105 {0xff, 0xff, 0x10, 0x00},
106 {0x10, 0x10, 0xff, 0x00},
107 {0xf0, 0x10, 0xff, 0x00},
108 {0x10, 0xff, 0xff, 0x00},
109 {0xff, 0xff, 0xff, 0x00},
110 };
111
112
113 UINTN
114 _IPrint (
115 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
116 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
117 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,
118 IN UINTN X,
119 IN UINTN Y,
120 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
121 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,
122 IN CHAR16 *fmt,
123 IN VA_LIST args
124 )
125 /*++
126
127 Routine Description:
128
129 Display string worker for: Print, PrintAt, IPrint, IPrintAt
130
131 Arguments:
132
133 GraphicsOutput - Graphics output protocol interface
134
135 UgaDraw - UGA draw protocol interface
136
137 Sto - Simple text out protocol interface
138
139 X - X coordinate to start printing
140
141 Y - Y coordinate to start printing
142
143 Foreground - Foreground color
144
145 Background - Background color
146
147 fmt - Format string
148
149 args - Print arguments
150
151 Returns:
152
153 Length of string printed to the console
154
155 --*/
156 {
157 VOID *Buffer;
158 EFI_STATUS Status;
159 UINTN Index;
160 CHAR16 *UnicodeWeight;
161 UINT32 HorizontalResolution;
162 UINT32 VerticalResolution;
163 UINT32 ColorDepth;
164 UINT32 RefreshRate;
165 UINTN BufferLen;
166 UINTN LineBufferLen;
167 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
168 EFI_HII_FONT_PROTOCOL *HiiFont;
169 EFI_IMAGE_OUTPUT *Blt;
170 EFI_FONT_DISPLAY_INFO *FontInfo;
171 #else
172 EFI_HII_PROTOCOL *Hii;
173 UINT16 GlyphWidth;
174 UINT32 GlyphStatus;
175 UINT16 StringIndex;
176 EFI_NARROW_GLYPH *Glyph;
177 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
178 #endif
179
180 //
181 // For now, allocate an arbitrarily long buffer
182 //
183 BufferLen = 0;
184 Buffer = EfiLibAllocateZeroPool (0x10000);
185 if (Buffer == NULL) {
186 return 0;
187 }
188
189 if (GraphicsOutput != NULL) {
190 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
191 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
192 } else {
193 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
194 }
195 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));
196
197 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
198 Blt = NULL;
199 FontInfo = NULL;
200 ASSERT (GraphicsOutput != NULL);
201 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);
202 if (EFI_ERROR (Status)) {
203 goto Error;
204 }
205 #else
206 LineBuffer = NULL;
207 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID**)&Hii);
208 if (EFI_ERROR (Status)) {
209 goto Error;
210 }
211 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;
212 LineBuffer = EfiLibAllocatePool (LineBufferLen);
213 if (LineBuffer == NULL) {
214 Status = EFI_OUT_OF_RESOURCES;
215 goto Error;
216 }
217 #endif
218
219 VSPrint (Buffer, 0x10000, fmt, args);
220
221 UnicodeWeight = (CHAR16 *) Buffer;
222
223 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {
224 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||
225 UnicodeWeight[Index] == CHAR_LINEFEED ||
226 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {
227 UnicodeWeight[Index] = 0;
228 }
229 }
230
231 BufferLen = EfiStrLen (Buffer);
232
233
234 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
235 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;
236 if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
237 Status = EFI_INVALID_PARAMETER;
238 goto Error;
239 }
240
241 Blt = (EFI_IMAGE_OUTPUT *) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
242 if (Blt == NULL) {
243 Status = EFI_OUT_OF_RESOURCES;
244 goto Error;
245 }
246
247 Blt->Width = (UINT16) (HorizontalResolution);
248 Blt->Height = (UINT16) (VerticalResolution);
249 Blt->Image.Screen = GraphicsOutput;
250
251 FontInfo = (EFI_FONT_DISPLAY_INFO *) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
252 if (FontInfo == NULL) {
253 Status = EFI_OUT_OF_RESOURCES;
254 goto Error;
255 }
256 if (Foreground != NULL) {
257 EfiCopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
258 } else {
259 EfiCopyMem (
260 &FontInfo->ForegroundColor,
261 &mEfiColors[Sto->Mode->Attribute & 0x0f],
262 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
263 );
264 }
265 if (Background != NULL) {
266 EfiCopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
267 } else {
268 EfiCopyMem (
269 &FontInfo->BackgroundColor,
270 &mEfiColors[Sto->Mode->Attribute >> 4],
271 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
272 );
273 }
274
275 Status = HiiFont->StringToImage (
276 HiiFont,
277 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,
278 Buffer,
279 FontInfo,
280 &Blt,
281 X,
282 Y,
283 NULL,
284 NULL,
285 NULL
286 );
287
288 #else
289 GlyphStatus = 0;
290
291 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
292 Status = EFI_INVALID_PARAMETER;
293 goto Error;
294 }
295
296 for (Index = 0; Index < BufferLen; Index++) {
297 StringIndex = (UINT16) Index;
298 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);
299 if (EFI_ERROR (Status)) {
300 goto Error;
301 }
302
303 if (Foreground == NULL || Background == NULL) {
304 Status = Hii->GlyphToBlt (
305 Hii,
306 (UINT8 *) Glyph,
307 mEfiColors[Sto->Mode->Attribute & 0x0f],
308 mEfiColors[Sto->Mode->Attribute >> 4],
309 BufferLen,
310 GlyphWidth,
311 GLYPH_HEIGHT,
312 &LineBuffer[Index * GLYPH_WIDTH]
313 );
314 } else {
315 Status = Hii->GlyphToBlt (
316 Hii,
317 (UINT8 *) Glyph,
318 *Foreground,
319 *Background,
320 BufferLen,
321 GlyphWidth,
322 GLYPH_HEIGHT,
323 &LineBuffer[Index * GLYPH_WIDTH]
324 );
325 }
326 }
327
328 //
329 // Blt a character to the screen
330 //
331 if (GraphicsOutput != NULL) {
332 Status = GraphicsOutput->Blt (
333 GraphicsOutput,
334 LineBuffer,
335 EfiBltBufferToVideo,
336 0,
337 0,
338 X,
339 Y,
340 GLYPH_WIDTH * BufferLen,
341 GLYPH_HEIGHT,
342 GLYPH_WIDTH * BufferLen * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
343 );
344 } else {
345 Status = UgaDraw->Blt (
346 UgaDraw,
347 (EFI_UGA_PIXEL *) LineBuffer,
348 EfiUgaBltBufferToVideo,
349 0,
350 0,
351 X,
352 Y,
353 GLYPH_WIDTH * BufferLen,
354 GLYPH_HEIGHT,
355 GLYPH_WIDTH * BufferLen * sizeof (EFI_UGA_PIXEL)
356 );
357 }
358
359 #endif
360
361 Error:
362 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
363 EfiLibSafeFreePool (Blt);
364 EfiLibSafeFreePool (FontInfo);
365 #else
366 EfiLibSafeFreePool (LineBuffer);
367 #endif
368 gBS->FreePool (Buffer);
369
370 if (EFI_ERROR (Status)) {
371 return 0;
372 }
373
374 return BufferLen;
375 }
376
377
378 UINTN
379 PrintXY (
380 IN UINTN X,
381 IN UINTN Y,
382 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
383 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
384 IN CHAR_W *Fmt,
385 ...
386 )
387 /*++
388
389 Routine Description:
390
391 Prints a formatted unicode string to the default console
392
393 Arguments:
394
395 X - X coordinate to start printing
396
397 Y - Y coordinate to start printing
398
399 ForeGround - Foreground color
400
401 BackGround - Background color
402
403 Fmt - Format string
404
405 ... - Print arguments
406
407 Returns:
408
409 Length of string printed to the console
410
411 --*/
412 {
413 EFI_HANDLE Handle;
414 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
415 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
416 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
417 EFI_STATUS Status;
418 VA_LIST Args;
419
420 VA_START (Args, Fmt);
421
422 Handle = gST->ConsoleOutHandle;
423
424 GraphicsOutput = NULL;
425 UgaDraw = NULL;
426 Status = gBS->HandleProtocol (
427 Handle,
428 &gEfiGraphicsOutputProtocolGuid,
429 (VOID**)&GraphicsOutput
430 );
431
432 if (EFI_ERROR (Status) || (GraphicsOutput == NULL)) {
433 GraphicsOutput = NULL;
434
435 Status = gBS->HandleProtocol (
436 Handle,
437 &gEfiUgaDrawProtocolGuid,
438 (VOID**)&UgaDraw
439 );
440
441 if (EFI_ERROR (Status) || (UgaDraw == NULL)) {
442 return 0;
443 }
444 }
445
446 Sto = NULL;
447 Status = gBS->HandleProtocol (
448 Handle,
449 &gEfiSimpleTextOutProtocolGuid,
450 (VOID**)&Sto
451 );
452
453 if (EFI_ERROR (Status) || (Sto == NULL)) {
454 return 0;
455 }
456
457 return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
458 }
459
460
461 UINTN
462 SPrint (
463 OUT CHAR_W *Buffer,
464 IN UINTN BufferSize,
465 IN CONST CHAR_W *Format,
466 ...
467 )
468 /*++
469
470 Routine Description:
471
472 SPrint function to process format and place the results in Buffer.
473
474 Arguments:
475
476 Buffer - Wide char buffer to print the results of the parsing of Format into.
477
478 BufferSize - Maximum number of characters to put into buffer. Zero means no
479 limit.
480
481 Format - Format string see file header for more details.
482
483 ... - Vararg list consumed by processing Format.
484
485 Returns:
486
487 Number of characters printed.
488
489 --*/
490 {
491 UINTN Return;
492 VA_LIST Marker;
493
494 VA_START (Marker, Format);
495 Return = VSPrint (Buffer, BufferSize, Format, Marker);
496 VA_END (Marker);
497
498 return Return;
499 }
500
501 UINTN
502 EFIAPI
503 VSPrint (
504 OUT CHAR_W *StartOfBuffer,
505 IN UINTN BufferSize,
506 IN CONST CHAR_W *FormatString,
507 IN VA_LIST Marker
508 )
509 /*++
510
511 Routine Description:
512
513 VSPrint function to process format and place the results in Buffer. Since a
514 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
515 this is the main print working routine
516
517 Arguments:
518
519 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
520
521 BufferSize - Maximum number of characters to put into buffer. Zero means
522 no limit.
523
524 FormatString - Unicode format string see file header for more details.
525
526 Marker - Vararg list consumed by processing Format.
527
528 Returns:
529
530 Number of characters printed.
531
532 --*/
533 {
534 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
535 CHAR_W *Buffer;
536 CHAR8 *AsciiStr;
537 CHAR16 *UnicodeStr;
538 CHAR_W *Format;
539 UINTN Index;
540 UINTN Flags;
541 UINTN Width;
542 UINTN Count;
543 UINTN NumberOfCharacters;
544 UINTN BufferLeft;
545 UINT64 Value;
546 EFI_GUID *TmpGUID;
547 BOOLEAN Done;
548
549 //
550 // Process the format string. Stop if Buffer is over run.
551 //
552
553 Buffer = StartOfBuffer;
554 Format = (CHAR_W *) FormatString;
555 NumberOfCharacters = BufferSize / sizeof (CHAR_W);
556 BufferLeft = BufferSize;
557 for (Index = 0; (*Format != '\0') && (Index < NumberOfCharacters - 1); Format++) {
558 if (*Format != '%') {
559 if ((*Format == '\n') && (Index < NumberOfCharacters - 2)) {
560 //
561 // If carage return add line feed
562 //
563 Buffer[Index++] = '\r';
564 BufferLeft -= sizeof (CHAR_W);
565 }
566
567 Buffer[Index++] = *Format;
568 BufferLeft -= sizeof (CHAR_W);
569 } else {
570
571 //
572 // Now it's time to parse what follows after %
573 //
574 Flags = 0;
575 Width = 0;
576 for (Done = FALSE; !Done;) {
577 Format++;
578
579 switch (*Format) {
580
581 case '-':
582 Flags |= LEFT_JUSTIFY;
583 break;
584
585 case '+':
586 Flags |= PREFIX_SIGN;
587 break;
588
589 case ' ':
590 Flags |= PREFIX_BLANK;
591 break;
592
593 case ',':
594 Flags |= COMMA_TYPE;
595 break;
596
597 case 'L':
598 case 'l':
599 Flags |= LONG_TYPE;
600 break;
601
602 case '*':
603 Width = VA_ARG (Marker, UINTN);
604 break;
605
606 case '0':
607 Flags |= PREFIX_ZERO;
608
609 case '1':
610 case '2':
611 case '3':
612 case '4':
613 case '5':
614 case '6':
615 case '7':
616 case '8':
617 case '9':
618 Count = 0;
619 do {
620 Count = (Count * 10) +*Format - '0';
621 Format++;
622 } while ((*Format >= '0') && (*Format <= '9'));
623 Format--;
624 Width = Count;
625 break;
626
627 default:
628 Done = TRUE;
629 }
630 }
631
632 switch (*Format) {
633 case 'p':
634 //
635 // Flag space, +, 0, L & l are invalid for type p.
636 //
637 Flags &= ~(PREFIX_BLANK| PREFIX_SIGN | LONG_TYPE);
638 if (sizeof (VOID *) > 4) {
639 Flags |= LONG_TYPE;
640 Value = VA_ARG (Marker, UINT64);
641 } else {
642 Value = VA_ARG (Marker, UINTN);
643 }
644 Flags |= PREFIX_ZERO;
645
646 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
647 UnicodeStr = TempBuffer;
648
649 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
650 Buffer[Index++] = *UnicodeStr;
651 }
652 break;
653
654 case 'X':
655 Flags |= PREFIX_ZERO;
656 Width = sizeof (UINT64) * 2;
657
658 //
659 // break skiped on purpose
660 //
661 case 'x':
662 if ((Flags & LONG_TYPE) == LONG_TYPE) {
663 Value = VA_ARG (Marker, UINT64);
664 } else {
665 Value = VA_ARG (Marker, UINTN);
666 }
667
668 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
669 UnicodeStr = TempBuffer;
670
671 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
672 Buffer[Index++] = *UnicodeStr;
673 }
674 break;
675
676 case 'd':
677 if ((Flags & LONG_TYPE) == LONG_TYPE) {
678 Value = VA_ARG (Marker, UINT64);
679 } else {
680 Value = (UINTN) VA_ARG (Marker, UINTN);
681 }
682
683 EfiValueToString (TempBuffer, Value, Flags, Width);
684 UnicodeStr = TempBuffer;
685
686 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
687 Buffer[Index++] = *UnicodeStr;
688 }
689 break;
690
691 case 's':
692 case 'S':
693 UnicodeStr = (CHAR16 *) VA_ARG (Marker, CHAR_W *);
694 if (UnicodeStr == NULL) {
695 UnicodeStr = L"<null string>";
696 }
697
698 for (Count = 0; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {
699 Buffer[Index++] = *UnicodeStr;
700 }
701 //
702 // Add padding if needed
703 //
704 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
705 Buffer[Index++] = ' ';
706 }
707
708 break;
709
710 case 'a':
711 AsciiStr = (CHAR8 *) VA_ARG (Marker, CHAR8 *);
712 if (AsciiStr == NULL) {
713 AsciiStr = (CHAR8 *) "<null string>";
714 }
715
716 for (Count = 0; (*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {
717 Buffer[Index++] = (CHAR_W) * AsciiStr;
718 }
719 //
720 // Add padding if needed
721 //
722 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
723 Buffer[Index++] = ' ';
724 }
725 break;
726
727 case 'c':
728 Buffer[Index++] = (CHAR_W) VA_ARG (Marker, UINTN);
729 break;
730
731 case 'g':
732 TmpGUID = VA_ARG (Marker, EFI_GUID *);
733 if (TmpGUID != NULL) {
734 Index += GuidToString (
735 TmpGUID,
736 &Buffer[Index],
737 BufferLeft
738 );
739 }
740 break;
741
742 case 't':
743 Index += TimeToString (
744 VA_ARG (Marker, EFI_TIME *),
745 &Buffer[Index],
746 BufferLeft
747 );
748 break;
749
750 case 'r':
751 Index += EfiStatusToString (
752 VA_ARG (Marker, EFI_STATUS),
753 &Buffer[Index],
754 BufferLeft
755 );
756 break;
757
758 case '%':
759 Buffer[Index++] = *Format;
760 break;
761
762 default:
763 //
764 // if the type is unknown print it to the screen
765 //
766 Buffer[Index++] = *Format;
767 }
768
769 BufferLeft = BufferSize - Index * sizeof (CHAR_W);
770 }
771 }
772
773 Buffer[Index++] = '\0';
774
775 return &Buffer[Index] - StartOfBuffer;
776 }
777
778 STATIC
779 UINTN
780 GuidToString (
781 IN EFI_GUID *Guid,
782 IN CHAR_W *Buffer,
783 IN UINTN BufferSize
784 )
785 /*++
786
787 Routine Description:
788
789 VSPrint worker function that prints an EFI_GUID.
790
791 Arguments:
792
793 Guid - Pointer to GUID to print.
794
795 Buffer - Buffe to print Guid into.
796
797 BufferSize - Size of Buffer.
798
799 Returns:
800
801 Number of characters printed.
802
803 --*/
804 {
805 UINTN Size;
806
807 Size = SPrint (
808 Buffer,
809 BufferSize,
810 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
811 (UINTN)Guid->Data1,
812 (UINTN)Guid->Data2,
813 (UINTN)Guid->Data3,
814 (UINTN)Guid->Data4[0],
815 (UINTN)Guid->Data4[1],
816 (UINTN)Guid->Data4[2],
817 (UINTN)Guid->Data4[3],
818 (UINTN)Guid->Data4[4],
819 (UINTN)Guid->Data4[5],
820 (UINTN)Guid->Data4[6],
821 (UINTN)Guid->Data4[7]
822 );
823
824 //
825 // SPrint will null terminate the string. The -1 skips the null
826 //
827 return Size - 1;
828 }
829
830
831 STATIC
832 UINTN
833 TimeToString (
834 IN EFI_TIME *Time,
835 OUT CHAR_W *Buffer,
836 IN UINTN BufferSize
837 )
838 /*++
839
840 Routine Description:
841
842 VSPrint worker function that prints EFI_TIME.
843
844 Arguments:
845
846 Time - Pointer to EFI_TIME sturcture to print.
847
848 Buffer - Buffer to print Time into.
849
850 BufferSize - Size of Buffer.
851
852 Returns:
853
854 Number of characters printed.
855
856 --*/
857 {
858 UINTN Size;
859
860 Size = SPrint (
861 Buffer,
862 BufferSize,
863 STRING_W ("%02d/%02d/%04d %02d:%02d"),
864 (UINTN)Time->Month,
865 (UINTN)Time->Day,
866 (UINTN)Time->Year,
867 (UINTN)Time->Hour,
868 (UINTN)Time->Minute
869 );
870
871 //
872 // SPrint will null terminate the string. The -1 skips the null
873 //
874 return Size - 1;
875 }
876
877 STATIC
878 UINTN
879 EfiStatusToString (
880 IN EFI_STATUS Status,
881 OUT CHAR_W *Buffer,
882 IN UINTN BufferSize
883 )
884 /*++
885
886 Routine Description:
887
888 VSPrint worker function that prints EFI_STATUS as a string. If string is
889 not known a hex value will be printed.
890
891 Arguments:
892
893 Status - EFI_STATUS sturcture to print.
894
895 Buffer - Buffer to print EFI_STATUS message string into.
896
897 BufferSize - Size of Buffer.
898
899 Returns:
900
901 Number of characters printed.
902
903 --*/
904 {
905 UINTN Size;
906 CHAR8 *Desc;
907
908 Desc = NULL;
909
910 //
911 // Can't use global Status String Array as UINTN is not constant for EBC
912 //
913 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else
914 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else
915 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else
916 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else
917 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else
918 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else
919 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else
920 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else
921 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else
922 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else
923 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else
924 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else
925 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else
926 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else
927 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else
928 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else
929 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else
930 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else
931 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else
932 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else
933 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else
934 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else
935 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else
936 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else
937 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else
938 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else
939 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else
940 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else
941 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; }
942
943 //
944 // If we found a match, copy the message to the user's buffer. Otherwise
945 // sprint the hex status code to their buffer.
946 //
947 if (Desc != NULL) {
948 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);
949 } else {
950 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);
951 }
952
953 return Size - 1;
954 }