source: mainline/boot/arch/ia64/loader/gefi/lib/print.c@ 7208b6c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7208b6c was 7208b6c, checked in by Jakub Vana <jakub.vana@…>, 17 years ago

Basic IA64 boot and kernel suport for real machines

  • Property mode set to 100644
File size: 24.4 KB
Line 
1/*++
2
3Copyright (c) 1998 Intel Corporation
4
5Module Name:
6
7 print.c
8
9Abstract:
10
11
12
13
14Revision History
15
16--*/
17
18#include "lib.h"
19#include "efistdarg.h" // !!!
20
21//
22// Declare runtime functions
23//
24
25#ifdef RUNTIME_CODE
26#pragma RUNTIME_CODE(DbgPrint)
27
28// For debugging..
29
30/*
31#pragma RUNTIME_CODE(_Print)
32#pragma RUNTIME_CODE(PFLUSH)
33#pragma RUNTIME_CODE(PSETATTR)
34#pragma RUNTIME_CODE(PPUTC)
35#pragma RUNTIME_CODE(PGETC)
36#pragma RUNTIME_CODE(PITEM)
37#pragma RUNTIME_CODE(ValueToHex)
38#pragma RUNTIME_CODE(ValueToString)
39#pragma RUNTIME_CODE(TimeToString)
40*/
41
42#endif
43
44//
45//
46//
47
48
49#define PRINT_STRING_LEN 200
50#define PRINT_ITEM_BUFFER_LEN 100
51
52typedef struct {
53 BOOLEAN Ascii;
54 UINTN Index;
55 union {
56 CHAR16 *pw;
57 CHAR8 *pc;
58 } un;
59} POINTER;
60
61#define pw un.pw
62#define pc un.pc
63
64typedef struct _pitem {
65
66 POINTER Item;
67 CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN];
68 UINTN Width;
69 UINTN FieldWidth;
70 UINTN *WidthParse;
71 CHAR16 Pad;
72 BOOLEAN PadBefore;
73 BOOLEAN Comma;
74 BOOLEAN Long;
75} PRINT_ITEM;
76
77
78typedef struct _pstate {
79 // Input
80 POINTER fmt;
81 va_list args;
82
83 // Output
84 CHAR16 *Buffer;
85 CHAR16 *End;
86 CHAR16 *Pos;
87 UINTN Len;
88
89 UINTN Attr;
90 UINTN RestoreAttr;
91
92 UINTN AttrNorm;
93 UINTN AttrHighlight;
94 UINTN AttrError;
95
96 INTN (*Output)(VOID *context, CHAR16 *str);
97 INTN (*SetAttr)(VOID *context, UINTN attr);
98 VOID *Context;
99
100 // Current item being formatted
101 struct _pitem *Item;
102} PRINT_STATE;
103
104//
105// Internal fucntions
106//
107
108STATIC
109UINTN
110_Print (
111 IN PRINT_STATE *ps
112 );
113
114STATIC
115UINTN
116_IPrint (
117 IN UINTN Column,
118 IN UINTN Row,
119 IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
120 IN CHAR16 *fmt,
121 IN CHAR8 *fmta,
122 IN va_list args
123 );
124
125STATIC
126INTN
127_DbgOut (
128 IN VOID *Context,
129 IN CHAR16 *Buffer
130 );
131
132STATIC
133VOID
134PFLUSH (
135 IN OUT PRINT_STATE *ps
136 );
137
138STATIC
139VOID
140PPUTC (
141 IN OUT PRINT_STATE *ps,
142 IN CHAR16 c
143 );
144
145STATIC
146VOID
147PITEM (
148 IN OUT PRINT_STATE *ps
149 );
150
151STATIC
152CHAR16
153PGETC (
154 IN POINTER *p
155 );
156
157STATIC
158VOID
159PSETATTR (
160 IN OUT PRINT_STATE *ps,
161 IN UINTN Attr
162 );
163
164//
165//
166//
167
168INTN
169DbgPrint (
170 IN INTN mask,
171 IN CHAR8 *fmt,
172 ...
173 )
174/*++
175
176Routine Description:
177
178 Prints a formatted unicode string to the default StandardError console
179
180Arguments:
181
182 mask - Bit mask of debug string. If a bit is set in the
183 mask that is also set in EFIDebug the string is
184 printed; otherwise, the string is not printed
185
186 fmt - Format string
187
188Returns:
189
190 Length of string printed to the StandardError console
191
192--*/
193{
194 SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
195 PRINT_STATE ps;
196 va_list args;
197 UINTN back;
198 UINTN attr;
199 UINTN SavedAttribute;
200
201
202 if (!(EFIDebug & mask)) {
203 return 0;
204 }
205
206 va_start (args, fmt);
207 ZeroMem (&ps, sizeof(ps));
208
209 ps.Output = _DbgOut;
210 ps.fmt.Ascii = TRUE;
211 ps.fmt.pc = fmt;
212 va_copy(ps.args, args);
213 ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED);
214
215 DbgOut = LibRuntimeDebugOut;
216
217 if (!DbgOut) {
218 DbgOut = ST->StdErr;
219 }
220
221 if (DbgOut) {
222 ps.Attr = DbgOut->Mode->Attribute;
223 ps.Context = DbgOut;
224 ps.SetAttr = (INTN (*)(VOID *, UINTN)) DbgOut->SetAttribute;
225 }
226
227 SavedAttribute = ps.Attr;
228
229 back = (ps.Attr >> 4) & 0xf;
230 ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
231 ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
232 ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
233
234 attr = ps.AttrNorm;
235
236 if (mask & D_WARN) {
237 attr = ps.AttrHighlight;
238 }
239
240 if (mask & D_ERROR) {
241 attr = ps.AttrError;
242 }
243
244 if (ps.SetAttr) {
245 ps.Attr = attr;
246 ps.SetAttr (ps.Context, attr);
247 }
248
249 _Print (&ps);
250
251 va_end (ps.args);
252 va_end (args);
253
254 //
255 // Restore original attributes
256 //
257
258 if (ps.SetAttr) {
259 ps.SetAttr (ps.Context, SavedAttribute);
260 }
261
262 return 0;
263}
264
265
266
267STATIC
268INTN
269_DbgOut (
270 IN VOID *Context,
271 IN CHAR16 *Buffer
272 )
273// Append string worker for DbgPrint
274{
275 SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
276
277 DbgOut = Context;
278// if (!DbgOut && ST && ST->ConOut) {
279// DbgOut = ST->ConOut;
280// }
281
282 if (DbgOut) {
283 DbgOut->OutputString (DbgOut, Buffer);
284 }
285
286 return 0;
287}
288
289INTN
290_SPrint (
291 IN VOID *Context,
292 IN CHAR16 *Buffer
293 )
294// Append string worker for SPrint, PoolPrint and CatPrint
295{
296 UINTN len;
297 POOL_PRINT *spc;
298
299 spc = Context;
300 len = StrLen(Buffer);
301
302 //
303 // Is the string is over the max truncate it
304 //
305
306 if (spc->len + len > spc->maxlen) {
307 len = spc->maxlen - spc->len;
308 }
309
310 //
311 // Append the new text
312 //
313
314 CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16));
315 spc->len += len;
316
317 //
318 // Null terminate it
319 //
320
321 if (spc->len < spc->maxlen) {
322 spc->str[spc->len] = 0;
323 } else if (spc->maxlen) {
324 spc->str[spc->maxlen-1] = 0;
325 }
326
327 return 0;
328}
329
330
331INTN
332_PoolPrint (
333 IN VOID *Context,
334 IN CHAR16 *Buffer
335 )
336// Append string worker for PoolPrint and CatPrint
337{
338 UINTN newlen;
339 POOL_PRINT *spc;
340
341 spc = Context;
342 newlen = spc->len + StrLen(Buffer) + 1;
343
344 //
345 // Is the string is over the max, grow the buffer
346 //
347
348 if (newlen > spc->maxlen) {
349
350 //
351 // Grow the pool buffer
352 //
353
354 newlen += PRINT_STRING_LEN;
355 spc->maxlen = newlen;
356 spc->str = ReallocatePool (
357 spc->str,
358 spc->len * sizeof(CHAR16),
359 spc->maxlen * sizeof(CHAR16)
360 );
361
362 if (!spc->str) {
363 spc->len = 0;
364 spc->maxlen = 0;
365 }
366 }
367
368 //
369 // Append the new text
370 //
371
372 return _SPrint (Context, Buffer);
373}
374
375
376
377VOID
378_PoolCatPrint (
379 IN CHAR16 *fmt,
380 IN va_list args,
381 IN OUT POOL_PRINT *spc,
382 IN INTN (*Output)(VOID *context, CHAR16 *str)
383 )
384// Dispath function for SPrint, PoolPrint, and CatPrint
385{
386 PRINT_STATE ps;
387
388 ZeroMem (&ps, sizeof(ps));
389 ps.Output = Output;
390 ps.Context = spc;
391 ps.fmt.pw = fmt;
392 va_copy(ps.args, args);
393 _Print (&ps);
394 va_end(ps.args);
395}
396
397
398
399UINTN
400SPrint (
401 OUT CHAR16 *Str,
402 IN UINTN StrSize,
403 IN CHAR16 *fmt,
404 ...
405 )
406/*++
407
408Routine Description:
409
410 Prints a formatted unicode string to a buffer
411
412Arguments:
413
414 Str - Output buffer to print the formatted string into
415
416 StrSize - Size of Str. String is truncated to this size.
417 A size of 0 means there is no limit
418
419 fmt - The format string
420
421Returns:
422
423 String length returned in buffer
424
425--*/
426{
427 POOL_PRINT spc;
428 va_list args;
429
430
431 va_start (args, fmt);
432 spc.str = Str;
433 spc.maxlen = StrSize / sizeof(CHAR16) - 1;
434 spc.len = 0;
435
436 _PoolCatPrint (fmt, args, &spc, _SPrint);
437 va_end (args);
438 return spc.len;
439}
440
441
442CHAR16 *
443PoolPrint (
444 IN CHAR16 *fmt,
445 ...
446 )
447/*++
448
449Routine Description:
450
451 Prints a formatted unicode string to allocated pool. The caller
452 must free the resulting buffer.
453
454Arguments:
455
456 fmt - The format string
457
458Returns:
459
460 Allocated buffer with the formatted string printed in it.
461 The caller must free the allocated buffer. The buffer
462 allocation is not packed.
463
464--*/
465{
466 POOL_PRINT spc;
467 va_list args;
468
469 ZeroMem (&spc, sizeof(spc));
470 va_start (args, fmt);
471 _PoolCatPrint (fmt, args, &spc, _PoolPrint);
472 va_end (args);
473 return spc.str;
474}
475
476
477
478CHAR16 *
479CatPrint (
480 IN OUT POOL_PRINT *Str,
481 IN CHAR16 *fmt,
482 ...
483 )
484/*++
485
486Routine Description:
487
488 Concatenates a formatted unicode string to allocated pool.
489 The caller must free the resulting buffer.
490
491Arguments:
492
493 Str - Tracks the allocated pool, size in use, and
494 amount of pool allocated.
495
496 fmt - The format string
497
498Returns:
499
500 Allocated buffer with the formatted string printed in it.
501 The caller must free the allocated buffer. The buffer
502 allocation is not packed.
503
504--*/
505{
506 va_list args;
507
508 va_start (args, fmt);
509 _PoolCatPrint (fmt, args, Str, _PoolPrint);
510 va_end (args);
511 return Str->str;
512}
513
514
515
516UINTN
517Print (
518 IN CHAR16 *fmt,
519 ...
520 )
521/*++
522
523Routine Description:
524
525 Prints a formatted unicode string to the default console
526
527Arguments:
528
529 fmt - Format string
530
531Returns:
532
533 Length of string printed to the console
534
535--*/
536{
537 va_list args;
538 UINTN back;
539
540 va_start (args, fmt);
541 back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
542 va_end (args);
543 return back;
544}
545
546UINTN
547VPrint (
548 IN CHAR16 *fmt,
549 va_list args
550 )
551/*++
552
553Routine Description:
554
555 Prints a formatted unicode string to the default console using a va_list
556
557Arguments:
558
559 fmt - Format string
560 args - va_list
561Returns:
562
563 Length of string printed to the console
564
565--*/
566{
567 return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
568}
569
570
571UINTN
572PrintAt (
573 IN UINTN Column,
574 IN UINTN Row,
575 IN CHAR16 *fmt,
576 ...
577 )
578/*++
579
580Routine Description:
581
582 Prints a formatted unicode string to the default console, at
583 the supplied cursor position
584
585Arguments:
586
587 Column, Row - The cursor position to print the string at
588
589 fmt - Format string
590
591Returns:
592
593 Length of string printed to the console
594
595--*/
596{
597 va_list args;
598 UINTN back;
599
600 va_start (args, fmt);
601 back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
602 va_end (args);
603 return back;
604}
605
606
607UINTN
608IPrint (
609 IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
610 IN CHAR16 *fmt,
611 ...
612 )
613/*++
614
615Routine Description:
616
617 Prints a formatted unicode string to the specified console
618
619Arguments:
620
621 Out - The console to print the string too
622
623 fmt - Format string
624
625Returns:
626
627 Length of string printed to the console
628
629--*/
630{
631 va_list args;
632 UINTN back;
633
634 va_start (args, fmt);
635 back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
636 va_end (args);
637 return back;
638}
639
640
641UINTN
642IPrintAt (
643 IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
644 IN UINTN Column,
645 IN UINTN Row,
646 IN CHAR16 *fmt,
647 ...
648 )
649/*++
650
651Routine Description:
652
653 Prints a formatted unicode string to the specified console, at
654 the supplied cursor position
655
656Arguments:
657
658 Out - The console to print the string too
659
660 Column, Row - The cursor position to print the string at
661
662 fmt - Format string
663
664Returns:
665
666 Length of string printed to the console
667
668--*/
669{
670 va_list args;
671 UINTN back;
672
673 va_start (args, fmt);
674 back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
675 va_end (args);
676 return back;
677}
678
679
680UINTN
681_IPrint (
682 IN UINTN Column,
683 IN UINTN Row,
684 IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
685 IN CHAR16 *fmt,
686 IN CHAR8 *fmta,
687 IN va_list args
688 )
689// Display string worker for: Print, PrintAt, IPrint, IPrintAt
690{
691 PRINT_STATE ps;
692 UINTN back;
693
694 ZeroMem (&ps, sizeof(ps));
695 ps.Context = Out;
696 ps.Output = (INTN (*)(VOID *, CHAR16 *)) Out->OutputString;
697 ps.SetAttr = (INTN (*)(VOID *, UINTN)) Out->SetAttribute;
698 ps.Attr = Out->Mode->Attribute;
699
700 back = (ps.Attr >> 4) & 0xF;
701 ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
702 ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
703 ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
704
705 if (fmt) {
706 ps.fmt.pw = fmt;
707 } else {
708 ps.fmt.Ascii = TRUE;
709 ps.fmt.pc = fmta;
710 }
711
712 va_copy(ps.args, args);
713
714 if (Column != (UINTN) -1) {
715 Out->SetCursorPosition(Out, Column, Row);
716 }
717
718 back = _Print (&ps);
719 va_end(ps.args);
720 return back;
721}
722
723
724UINTN
725APrint (
726 IN CHAR8 *fmt,
727 ...
728 )
729/*++
730
731Routine Description:
732
733 For those whom really can't deal with unicode, a print
734 function that takes an ascii format string
735
736Arguments:
737
738 fmt - ascii format string
739
740Returns:
741
742 Length of string printed to the console
743
744--*/
745
746{
747 va_list args;
748 UINTN back;
749
750 va_start (args, fmt);
751 back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
752 va_end (args);
753 return back;
754}
755
756
757STATIC
758VOID
759PFLUSH (
760 IN OUT PRINT_STATE *ps
761 )
762{
763 *ps->Pos = 0;
764 ps->Output(ps->Context, ps->Buffer);
765 ps->Pos = ps->Buffer;
766}
767
768STATIC
769VOID
770PSETATTR (
771 IN OUT PRINT_STATE *ps,
772 IN UINTN Attr
773 )
774{
775 PFLUSH (ps);
776
777 ps->RestoreAttr = ps->Attr;
778 if (ps->SetAttr) {
779 ps->SetAttr (ps->Context, Attr);
780 }
781
782 ps->Attr = Attr;
783}
784
785STATIC
786VOID
787PPUTC (
788 IN OUT PRINT_STATE *ps,
789 IN CHAR16 c
790 )
791{
792 // if this is a newline, add a carraige return
793 if (c == '\n') {
794 PPUTC (ps, '\r');
795 }
796
797 *ps->Pos = c;
798 ps->Pos += 1;
799 ps->Len += 1;
800
801 // if at the end of the buffer, flush it
802 if (ps->Pos >= ps->End) {
803 PFLUSH(ps);
804 }
805}
806
807
808STATIC
809CHAR16
810PGETC (
811 IN POINTER *p
812 )
813{
814 CHAR16 c;
815
816 c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
817 p->Index += 1;
818
819 return c;
820}
821
822
823STATIC
824VOID
825PITEM (
826 IN OUT PRINT_STATE *ps
827 )
828{
829 UINTN Len, i;
830 PRINT_ITEM *Item;
831 CHAR16 c;
832
833 // Get the length of the item
834 Item = ps->Item;
835 Item->Item.Index = 0;
836 while (Item->Item.Index < Item->FieldWidth) {
837 c = PGETC(&Item->Item);
838 if (!c) {
839 Item->Item.Index -= 1;
840 break;
841 }
842 }
843 Len = Item->Item.Index;
844
845 // if there is no item field width, use the items width
846 if (Item->FieldWidth == (UINTN) -1) {
847 Item->FieldWidth = Len;
848 }
849
850 // if item is larger then width, update width
851 if (Len > Item->Width) {
852 Item->Width = Len;
853 }
854
855
856 // if pad field before, add pad char
857 if (Item->PadBefore) {
858 for (i=Item->Width; i < Item->FieldWidth; i+=1) {
859 PPUTC (ps, ' ');
860 }
861 }
862
863 // pad item
864 for (i=Len; i < Item->Width; i++) {
865 PPUTC (ps, Item->Pad);
866 }
867
868 // add the item
869 Item->Item.Index=0;
870 while (Item->Item.Index < Len) {
871 PPUTC (ps, PGETC(&Item->Item));
872 }
873
874 // If pad at the end, add pad char
875 if (!Item->PadBefore) {
876 for (i=Item->Width; i < Item->FieldWidth; i+=1) {
877 PPUTC (ps, ' ');
878 }
879 }
880}
881
882
883STATIC
884UINTN
885_Print (
886 IN PRINT_STATE *ps
887 )
888/*++
889
890Routine Description:
891
892 %w.lF - w = width
893 l = field width
894 F = format of arg
895
896 Args F:
897 0 - pad with zeros
898 - - justify on left (default is on right)
899 , - add comma's to field
900 * - width provided on stack
901 n - Set output attribute to normal (for this field only)
902 h - Set output attribute to highlight (for this field only)
903 e - Set output attribute to error (for this field only)
904 l - Value is 64 bits
905
906 a - ascii string
907 s - unicode string
908 X - fixed 8 byte value in hex
909 x - hex value
910 d - value as decimal
911 c - Unicode char
912 t - EFI time structure
913 g - Pointer to GUID
914 r - EFI status code (result code)
915
916 N - Set output attribute to normal
917 H - Set output attribute to highlight
918 E - Set output attribute to error
919 % - Print a %
920
921Arguments:
922
923 SystemTable - The system table
924
925Returns:
926
927 Number of charactors written
928
929--*/
930{
931 CHAR16 c;
932 UINTN Attr;
933 PRINT_ITEM Item;
934 CHAR16 Buffer[PRINT_STRING_LEN];
935
936 ps->Len = 0;
937 ps->Buffer = Buffer;
938 ps->Pos = Buffer;
939 ps->End = Buffer + PRINT_STRING_LEN - 1;
940 ps->Item = &Item;
941
942 ps->fmt.Index = 0;
943 while ((c = PGETC(&ps->fmt))) {
944
945 if (c != '%') {
946 PPUTC ( ps, c );
947 continue;
948 }
949
950 // setup for new item
951 Item.FieldWidth = (UINTN) -1;
952 Item.Width = 0;
953 Item.WidthParse = &Item.Width;
954 Item.Pad = ' ';
955 Item.PadBefore = TRUE;
956 Item.Comma = FALSE;
957 Item.Long = FALSE;
958 Item.Item.Ascii = FALSE;
959 Item.Item.pw = NULL;
960 ps->RestoreAttr = 0;
961 Attr = 0;
962
963 while ((c = PGETC(&ps->fmt))) {
964
965 switch (c) {
966
967 case '%':
968 //
969 // %% -> %
970 //
971 Item.Item.pw = Item.Scratch;
972 Item.Item.pw[0] = '%';
973 Item.Item.pw[1] = 0;
974 break;
975
976 case '0':
977 Item.Pad = '0';
978 break;
979
980 case '-':
981 Item.PadBefore = FALSE;
982 break;
983
984 case ',':
985 Item.Comma = TRUE;
986 break;
987
988 case '.':
989 Item.WidthParse = &Item.FieldWidth;
990 break;
991
992 case '*':
993 *Item.WidthParse = va_arg(ps->args, UINTN);
994 break;
995
996 case '1':
997 case '2':
998 case '3':
999 case '4':
1000 case '5':
1001 case '6':
1002 case '7':
1003 case '8':
1004 case '9':
1005 *Item.WidthParse = 0;
1006 do {
1007 *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
1008 c = PGETC(&ps->fmt);
1009 } while (c >= '0' && c <= '9') ;
1010 ps->fmt.Index -= 1;
1011 break;
1012
1013 case 'a':
1014 Item.Item.pc = va_arg(ps->args, CHAR8 *);
1015 Item.Item.Ascii = TRUE;
1016 if (!Item.Item.pc) {
1017 Item.Item.pc = (CHAR8 *)"(null)";
1018 }
1019 break;
1020
1021 case 's':
1022 Item.Item.pw = va_arg(ps->args, CHAR16 *);
1023 if (!Item.Item.pw) {
1024 Item.Item.pw = L"(null)";
1025 }
1026 break;
1027
1028 case 'c':
1029 Item.Item.pw = Item.Scratch;
1030 Item.Item.pw[0] = (CHAR16) va_arg(ps->args, UINTN);
1031 Item.Item.pw[1] = 0;
1032 break;
1033
1034 case 'l':
1035 Item.Long = TRUE;
1036 break;
1037
1038 case 'X':
1039 Item.Width = Item.Long ? 16 : 8;
1040 Item.Pad = '0';
1041 case 'x':
1042 Item.Item.pw = Item.Scratch;
1043 ValueToHex (
1044 Item.Item.pw,
1045 Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINTN)
1046 );
1047
1048 break;
1049
1050
1051 case 'g':
1052 Item.Item.pw = Item.Scratch;
1053 GuidToString (Item.Item.pw, va_arg(ps->args, EFI_GUID *));
1054 break;
1055
1056 case 'd':
1057 Item.Item.pw = Item.Scratch;
1058 ValueToString (
1059 Item.Item.pw,
1060 Item.Comma,
1061 Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINTN)
1062 );
1063 break
1064 ;
1065 case 't':
1066 Item.Item.pw = Item.Scratch;
1067 TimeToString (Item.Item.pw, va_arg(ps->args, EFI_TIME *));
1068 break;
1069
1070 case 'r':
1071 Item.Item.pw = Item.Scratch;
1072 StatusToString (Item.Item.pw, va_arg(ps->args, EFI_STATUS));
1073 break;
1074
1075 case 'n':
1076 PSETATTR(ps, ps->AttrNorm);
1077 break;
1078
1079 case 'h':
1080 PSETATTR(ps, ps->AttrHighlight);
1081 break;
1082
1083 case 'e':
1084 PSETATTR(ps, ps->AttrError);
1085 break;
1086
1087 case 'N':
1088 Attr = ps->AttrNorm;
1089 break;
1090
1091 case 'H':
1092 Attr = ps->AttrHighlight;
1093 break;
1094
1095 case 'E':
1096 Attr = ps->AttrError;
1097 break;
1098
1099 default:
1100 Item.Item.pw = Item.Scratch;
1101 Item.Item.pw[0] = '?';
1102 Item.Item.pw[1] = 0;
1103 break;
1104 }
1105
1106 // if we have an Item
1107 if (Item.Item.pw) {
1108 PITEM (ps);
1109 break;
1110 }
1111
1112 // if we have an Attr set
1113 if (Attr) {
1114 PSETATTR(ps, Attr);
1115 ps->RestoreAttr = 0;
1116 break;
1117 }
1118 }
1119
1120 if (ps->RestoreAttr) {
1121 PSETATTR(ps, ps->RestoreAttr);
1122 }
1123 }
1124
1125 // Flush buffer
1126 PFLUSH (ps);
1127 return ps->Len;
1128}
1129
1130STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
1131 '8','9','A','B','C','D','E','F'};
1132
1133VOID
1134ValueToHex (
1135 IN CHAR16 *Buffer,
1136 IN UINT64 v
1137 )
1138{
1139 CHAR8 str[30], *p1;
1140 CHAR16 *p2;
1141
1142 if (!v) {
1143 Buffer[0] = '0';
1144 Buffer[1] = 0;
1145 return ;
1146 }
1147
1148 p1 = str;
1149 p2 = Buffer;
1150
1151 while (v) {
1152 *(p1++) = Hex[v & 0xf];
1153 v = RShiftU64 (v, 4);
1154 }
1155
1156 while (p1 != str) {
1157 *(p2++) = *(--p1);
1158 }
1159 *p2 = 0;
1160}
1161
1162
1163VOID
1164ValueToString (
1165 IN CHAR16 *Buffer,
1166 IN BOOLEAN Comma,
1167 IN INT64 v
1168 )
1169{
1170 STATIC CHAR8 ca[] = { 3, 1, 2 };
1171 CHAR8 str[40], *p1;
1172 CHAR16 *p2;
1173 UINTN c, r;
1174
1175 if (!v) {
1176 Buffer[0] = '0';
1177 Buffer[1] = 0;
1178 return ;
1179 }
1180
1181 p1 = str;
1182 p2 = Buffer;
1183
1184 if (v < 0) {
1185 *(p2++) = '-';
1186 v = -v;
1187 }
1188
1189 while (v) {
1190 v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
1191 *(p1++) = (CHAR8)r + '0';
1192 }
1193
1194 c = (Comma ? ca[(p1 - str) % 3] : 999) + 1;
1195 while (p1 != str) {
1196
1197 c -= 1;
1198 if (!c) {
1199 *(p2++) = ',';
1200 c = 3;
1201 }
1202
1203 *(p2++) = *(--p1);
1204 }
1205 *p2 = 0;
1206}
1207
1208VOID
1209TimeToString (
1210 OUT CHAR16 *Buffer,
1211 IN EFI_TIME *Time
1212 )
1213{
1214 UINTN Hour, Year;
1215 CHAR16 AmPm;
1216
1217 AmPm = 'a';
1218 Hour = Time->Hour;
1219 if (Time->Hour == 0) {
1220 Hour = 12;
1221 } else if (Time->Hour >= 12) {
1222 AmPm = 'p';
1223 if (Time->Hour >= 13) {
1224 Hour -= 12;
1225 }
1226 }
1227
1228 Year = Time->Year % 100;
1229
1230 // bugbug: for now just print it any old way
1231 SPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c",
1232 Time->Month,
1233 Time->Day,
1234 Year,
1235 Hour,
1236 Time->Minute,
1237 AmPm
1238 );
1239}
1240
1241
1242
1243
1244VOID
1245DumpHex (
1246 IN UINTN Indent,
1247 IN UINTN Offset,
1248 IN UINTN DataSize,
1249 IN VOID *UserData
1250 )
1251{
1252 CHAR8 *Data, Val[50], Str[20], c;
1253 UINTN Size, Index;
1254
1255 UINTN ScreenCount;
1256 UINTN TempColumn;
1257 UINTN ScreenSize;
1258 CHAR16 ReturnStr[1];
1259
1260
1261 ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
1262 ScreenCount = 0;
1263 ScreenSize -= 2;
1264
1265 Data = UserData;
1266 while (DataSize) {
1267 Size = 16;
1268 if (Size > DataSize) {
1269 Size = DataSize;
1270 }
1271
1272 for (Index=0; Index < Size; Index += 1) {
1273 c = Data[Index];
1274 Val[Index*3+0] = Hex[c>>4];
1275 Val[Index*3+1] = Hex[c&0xF];
1276 Val[Index*3+2] = (Index == 7)?'-':' ';
1277 Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
1278 }
1279
1280 Val[Index*3] = 0;
1281 Str[Index] = 0;
1282 Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
1283
1284 Data += Size;
1285 Offset += Size;
1286 DataSize -= Size;
1287
1288 ScreenCount++;
1289 if (ScreenCount >= ScreenSize && ScreenSize != 0) {
1290 //
1291 // If ScreenSize == 0 we have the console redirected so don't
1292 // block updates
1293 //
1294 ScreenCount = 0;
1295 Print (L"Press Enter to continue :");
1296 Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
1297 Print (L"\n");
1298 }
1299
1300 }
1301}
Note: See TracBrowser for help on using the repository browser.