diff options
Diffstat (limited to 'gnu-efi/gnu-efi-3.0/lib/print.c')
-rw-r--r-- | gnu-efi/gnu-efi-3.0/lib/print.c | 1366 |
1 files changed, 1366 insertions, 0 deletions
diff --git a/gnu-efi/gnu-efi-3.0/lib/print.c b/gnu-efi/gnu-efi-3.0/lib/print.c new file mode 100644 index 0000000..eaea90c --- /dev/null +++ b/gnu-efi/gnu-efi-3.0/lib/print.c @@ -0,0 +1,1366 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + print.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" +#include "efistdarg.h" // !!! + +// +// Declare runtime functions +// + +#ifdef RUNTIME_CODE +#ifndef __GNUC__ +#pragma RUNTIME_CODE(DbgPrint) + +// For debugging.. + +/* +#pragma RUNTIME_CODE(_Print) +#pragma RUNTIME_CODE(PFLUSH) +#pragma RUNTIME_CODE(PSETATTR) +#pragma RUNTIME_CODE(PPUTC) +#pragma RUNTIME_CODE(PGETC) +#pragma RUNTIME_CODE(PITEM) +#pragma RUNTIME_CODE(ValueToHex) +#pragma RUNTIME_CODE(ValueToString) +#pragma RUNTIME_CODE(TimeToString) +*/ + +#endif /* !defined(__GNUC__) */ +#endif + +// +// +// + + +#define PRINT_STRING_LEN 200 +#define PRINT_ITEM_BUFFER_LEN 100 + +typedef struct { + BOOLEAN Ascii; + UINTN Index; + union { + CHAR16 *pw; + CHAR8 *pc; + } un; +} POINTER; + +#define pw un.pw +#define pc un.pc + +typedef struct _pitem { + + POINTER Item; + CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN]; + UINTN Width; + UINTN FieldWidth; + UINTN *WidthParse; + CHAR16 Pad; + BOOLEAN PadBefore; + BOOLEAN Comma; + BOOLEAN Long; +} PRINT_ITEM; + + +typedef struct _pstate { + // Input + POINTER fmt; + va_list args; + + // Output + CHAR16 *Buffer; + CHAR16 *End; + CHAR16 *Pos; + UINTN Len; + + UINTN Attr; + UINTN RestoreAttr; + + UINTN AttrNorm; + UINTN AttrHighlight; + UINTN AttrError; + + INTN EFIAPI (*Output)(VOID *context, CHAR16 *str); + INTN EFIAPI (*SetAttr)(VOID *context, UINTN attr); + VOID *Context; + + // Current item being formatted + struct _pitem *Item; +} PRINT_STATE; + +// +// Internal fucntions +// + +STATIC +UINTN +_Print ( + IN PRINT_STATE *ps + ); + +STATIC +UINTN +_IPrint ( + IN UINTN Column, + IN UINTN Row, + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CHAR16 *fmt, + IN CHAR8 *fmta, + IN va_list args + ); + +STATIC +INTN EFIAPI +_DbgOut ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +STATIC +VOID +PFLUSH ( + IN OUT PRINT_STATE *ps + ); + +STATIC +VOID +PPUTC ( + IN OUT PRINT_STATE *ps, + IN CHAR16 c + ); + +STATIC +VOID +PITEM ( + IN OUT PRINT_STATE *ps + ); + +STATIC +CHAR16 +PGETC ( + IN POINTER *p + ); + +STATIC +VOID +PSETATTR ( + IN OUT PRINT_STATE *ps, + IN UINTN Attr + ); + +// +// +// + +INTN EFIAPI +_SPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +INTN EFIAPI +_PoolPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +INTN +DbgPrint ( + IN INTN mask, + IN CHAR8 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the default StandardError console + +Arguments: + + mask - Bit mask of debug string. If a bit is set in the + mask that is also set in EFIDebug the string is + printed; otherwise, the string is not printed + + fmt - Format string + +Returns: + + Length of string printed to the StandardError console + +--*/ +{ + SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut; + PRINT_STATE ps; + va_list args; + UINTN back; + UINTN attr; + UINTN SavedAttribute; + + + if (!(EFIDebug & mask)) { + return 0; + } + + va_start (args, fmt); + ZeroMem (&ps, sizeof(ps)); + + ps.Output = _DbgOut; + ps.fmt.Ascii = TRUE; + ps.fmt.pc = fmt; + va_copy(ps.args, args); + ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED); + + DbgOut = LibRuntimeDebugOut; + + if (!DbgOut) { + DbgOut = ST->StdErr; + } + + if (DbgOut) { + ps.Attr = DbgOut->Mode->Attribute; + ps.Context = DbgOut; + ps.SetAttr = (INTN EFIAPI (*)(VOID *, UINTN)) DbgOut->SetAttribute; + } + + SavedAttribute = ps.Attr; + + back = (ps.Attr >> 4) & 0xf; + ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back); + ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back); + ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back); + + attr = ps.AttrNorm; + + if (mask & D_WARN) { + attr = ps.AttrHighlight; + } + + if (mask & D_ERROR) { + attr = ps.AttrError; + } + + if (ps.SetAttr) { + ps.Attr = attr; + ps.SetAttr (ps.Context, attr); + } + + _Print (&ps); + + va_end (ps.args); + va_end (args); + + // + // Restore original attributes + // + + if (ps.SetAttr) { + ps.SetAttr (ps.Context, SavedAttribute); + } + + return 0; +} + +STATIC +INTN +IsLocalPrint(void *func) +{ + if (func == _DbgOut || func == _SPrint || func == _PoolPrint) + return 1; + return 0; +} + +STATIC +INTN EFIAPI +_DbgOut ( + IN VOID *Context, + IN CHAR16 *Buffer + ) +// Append string worker for DbgPrint +{ + SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut; + + DbgOut = Context; +// if (!DbgOut && ST && ST->ConOut) { +// DbgOut = ST->ConOut; +// } + + if (DbgOut) { + if (IsLocalPrint(DbgOut->OutputString)) + DbgOut->OutputString(DbgOut, Buffer); + else + uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer); + } + + return 0; +} + +INTN EFIAPI +_SPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ) +// Append string worker for SPrint, PoolPrint and CatPrint +{ + UINTN len; + POOL_PRINT *spc; + + spc = Context; + len = StrLen(Buffer); + + // + // Is the string is over the max truncate it + // + + if (spc->len + len > spc->maxlen) { + len = spc->maxlen - spc->len; + } + + // + // Append the new text + // + + CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16)); + spc->len += len; + + // + // Null terminate it + // + + if (spc->len < spc->maxlen) { + spc->str[spc->len] = 0; + } else if (spc->maxlen) { + spc->str[spc->maxlen-1] = 0; + } + + return 0; +} + + +INTN EFIAPI +_PoolPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ) +// Append string worker for PoolPrint and CatPrint +{ + UINTN newlen; + POOL_PRINT *spc; + + spc = Context; + newlen = spc->len + StrLen(Buffer) + 1; + + // + // Is the string is over the max, grow the buffer + // + + if (newlen > spc->maxlen) { + + // + // Grow the pool buffer + // + + newlen += PRINT_STRING_LEN; + spc->maxlen = newlen; + spc->str = ReallocatePool ( + spc->str, + spc->len * sizeof(CHAR16), + spc->maxlen * sizeof(CHAR16) + ); + + if (!spc->str) { + spc->len = 0; + spc->maxlen = 0; + } + } + + // + // Append the new text + // + + return _SPrint (Context, Buffer); +} + + + +VOID +_PoolCatPrint ( + IN CHAR16 *fmt, + IN va_list args, + IN OUT POOL_PRINT *spc, + IN INTN EFIAPI (*Output)(VOID *context, CHAR16 *str) + ) +// Dispath function for SPrint, PoolPrint, and CatPrint +{ + PRINT_STATE ps; + + ZeroMem (&ps, sizeof(ps)); + ps.Output = Output; + ps.Context = spc; + ps.fmt.pw = fmt; + va_copy(ps.args, args); + _Print (&ps); + va_end(ps.args); +} + + + +UINTN +VSPrint ( + OUT CHAR16 *Str, + IN UINTN StrSize, + IN CHAR16 *fmt, + va_list args + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to a buffer using a va_list + +Arguments: + + Str - Output buffer to print the formatted string into + + StrSize - Size of Str. String is truncated to this size. + A size of 0 means there is no limit + + fmt - The format string + + args - va_list + + +Returns: + + String length returned in buffer + +--*/ +{ + POOL_PRINT spc; + + spc.str = Str; + spc.maxlen = StrSize / sizeof(CHAR16) - 1; + spc.len = 0; + + _PoolCatPrint (fmt, args, &spc, _SPrint); + + return spc.len; +} + +UINTN +SPrint ( + OUT CHAR16 *Str, + IN UINTN StrSize, + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to a buffer + +Arguments: + + Str - Output buffer to print the formatted string into + + StrSize - Size of Str. String is truncated to this size. + A size of 0 means there is no limit + + fmt - The format string + +Returns: + + String length returned in buffer + +--*/ +{ + va_list args; + UINTN len; + + va_start (args, fmt); + len = VSPrint(Str, StrSize, fmt, args); + va_end (args); + + return len; +} + + +CHAR16 * +PoolPrint ( + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to allocated pool. The caller + must free the resulting buffer. + +Arguments: + + fmt - The format string + +Returns: + + Allocated buffer with the formatted string printed in it. + The caller must free the allocated buffer. The buffer + allocation is not packed. + +--*/ +{ + POOL_PRINT spc; + va_list args; + + ZeroMem (&spc, sizeof(spc)); + va_start (args, fmt); + _PoolCatPrint (fmt, args, &spc, _PoolPrint); + va_end (args); + return spc.str; +} + + + +CHAR16 * +CatPrint ( + IN OUT POOL_PRINT *Str, + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Concatenates a formatted unicode string to allocated pool. + The caller must free the resulting buffer. + +Arguments: + + Str - Tracks the allocated pool, size in use, and + amount of pool allocated. + + fmt - The format string + +Returns: + + Allocated buffer with the formatted string printed in it. + The caller must free the allocated buffer. The buffer + allocation is not packed. + +--*/ +{ + va_list args; + + va_start (args, fmt); + _PoolCatPrint (fmt, args, Str, _PoolPrint); + va_end (args); + return Str->str; +} + + + +UINTN +Print ( + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the default console + +Arguments: + + fmt - Format string + +Returns: + + Length of string printed to the console + +--*/ +{ + va_list args; + UINTN back; + + va_start (args, fmt); + back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args); + va_end (args); + return back; +} + +UINTN +VPrint ( + IN CHAR16 *fmt, + va_list args + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the default console using a va_list + +Arguments: + + fmt - Format string + args - va_list +Returns: + + Length of string printed to the console + +--*/ +{ + return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args); +} + + +UINTN +PrintAt ( + IN UINTN Column, + IN UINTN Row, + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the default console, at + the supplied cursor position + +Arguments: + + Column, Row - The cursor position to print the string at + + fmt - Format string + +Returns: + + Length of string printed to the console + +--*/ +{ + va_list args; + UINTN back; + + va_start (args, fmt); + back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args); + va_end (args); + return back; +} + + +UINTN +IPrint ( + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the specified console + +Arguments: + + Out - The console to print the string too + + fmt - Format string + +Returns: + + Length of string printed to the console + +--*/ +{ + va_list args; + UINTN back; + + va_start (args, fmt); + back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args); + va_end (args); + return back; +} + + +UINTN +IPrintAt ( + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN UINTN Column, + IN UINTN Row, + IN CHAR16 *fmt, + ... + ) +/*++ + +Routine Description: + + Prints a formatted unicode string to the specified console, at + the supplied cursor position + +Arguments: + + Out - The console to print the string too + + Column, Row - The cursor position to print the string at + + fmt - Format string + +Returns: + + Length of string printed to the console + +--*/ +{ + va_list args; + UINTN back; + + va_start (args, fmt); + back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args); + va_end (args); + return back; +} + + +UINTN +_IPrint ( + IN UINTN Column, + IN UINTN Row, + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CHAR16 *fmt, + IN CHAR8 *fmta, + IN va_list args + ) +// Display string worker for: Print, PrintAt, IPrint, IPrintAt +{ + PRINT_STATE ps; + UINTN back; + + ZeroMem (&ps, sizeof(ps)); + ps.Context = Out; + ps.Output = (INTN EFIAPI (*)(VOID *, CHAR16 *)) Out->OutputString; + ps.SetAttr = (INTN EFIAPI (*)(VOID *, UINTN)) Out->SetAttribute; + ps.Attr = Out->Mode->Attribute; + + back = (ps.Attr >> 4) & 0xF; + ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back); + ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back); + ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back); + + if (fmt) { + ps.fmt.pw = fmt; + } else { + ps.fmt.Ascii = TRUE; + ps.fmt.pc = fmta; + } + + va_copy(ps.args, args); + + if (Column != (UINTN) -1) { + uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row); + } + + back = _Print (&ps); + va_end(ps.args); + return back; +} + + +UINTN +APrint ( + IN CHAR8 *fmt, + ... + ) +/*++ + +Routine Description: + + For those whom really can't deal with unicode, a print + function that takes an ascii format string + +Arguments: + + fmt - ascii format string + +Returns: + + Length of string printed to the console + +--*/ + +{ + va_list args; + UINTN back; + + va_start (args, fmt); + back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args); + va_end (args); + return back; +} + + +STATIC +VOID +PFLUSH ( + IN OUT PRINT_STATE *ps + ) +{ + *ps->Pos = 0; + if (IsLocalPrint(ps->Output)) + ps->Output(ps->Context, ps->Buffer); + else + uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer); + ps->Pos = ps->Buffer; +} + +STATIC +VOID +PSETATTR ( + IN OUT PRINT_STATE *ps, + IN UINTN Attr + ) +{ + PFLUSH (ps); + + ps->RestoreAttr = ps->Attr; + if (ps->SetAttr) { + uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr); + } + + ps->Attr = Attr; +} + +STATIC +VOID +PPUTC ( + IN OUT PRINT_STATE *ps, + IN CHAR16 c + ) +{ + // if this is a newline, add a carraige return + if (c == '\n') { + PPUTC (ps, '\r'); + } + + *ps->Pos = c; + ps->Pos += 1; + ps->Len += 1; + + // if at the end of the buffer, flush it + if (ps->Pos >= ps->End) { + PFLUSH(ps); + } +} + + +STATIC +CHAR16 +PGETC ( + IN POINTER *p + ) +{ + CHAR16 c; + + c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index]; + p->Index += 1; + + return c; +} + + +STATIC +VOID +PITEM ( + IN OUT PRINT_STATE *ps + ) +{ + UINTN Len, i; + PRINT_ITEM *Item; + CHAR16 c; + + // Get the length of the item + Item = ps->Item; + Item->Item.Index = 0; + while (Item->Item.Index < Item->FieldWidth) { + c = PGETC(&Item->Item); + if (!c) { + Item->Item.Index -= 1; + break; + } + } + Len = Item->Item.Index; + + // if there is no item field width, use the items width + if (Item->FieldWidth == (UINTN) -1) { + Item->FieldWidth = Len; + } + + // if item is larger then width, update width + if (Len > Item->Width) { + Item->Width = Len; + } + + + // if pad field before, add pad char + if (Item->PadBefore) { + for (i=Item->Width; i < Item->FieldWidth; i+=1) { + PPUTC (ps, ' '); + } + } + + // pad item + for (i=Len; i < Item->Width; i++) { + PPUTC (ps, Item->Pad); + } + + // add the item + Item->Item.Index=0; + while (Item->Item.Index < Len) { + PPUTC (ps, PGETC(&Item->Item)); + } + + // If pad at the end, add pad char + if (!Item->PadBefore) { + for (i=Item->Width; i < Item->FieldWidth; i+=1) { + PPUTC (ps, ' '); + } + } +} + + +STATIC +UINTN +_Print ( + IN PRINT_STATE *ps + ) +/*++ + +Routine Description: + + %w.lF - w = width + l = field width + F = format of arg + + Args F: + 0 - pad with zeros + - - justify on left (default is on right) + , - add comma's to field + * - width provided on stack + n - Set output attribute to normal (for this field only) + h - Set output attribute to highlight (for this field only) + e - Set output attribute to error (for this field only) + l - Value is 64 bits + + a - ascii string + s - unicode string + X - fixed 8 byte value in hex + x - hex value + d - value as decimal + c - Unicode char + t - EFI time structure + g - Pointer to GUID + r - EFI status code (result code) + + N - Set output attribute to normal + H - Set output attribute to highlight + E - Set output attribute to error + % - Print a % + +Arguments: + + SystemTable - The system table + +Returns: + + Number of charactors written + +--*/ +{ + CHAR16 c; + UINTN Attr; + PRINT_ITEM Item; + CHAR16 Buffer[PRINT_STRING_LEN]; + + ps->Len = 0; + ps->Buffer = Buffer; + ps->Pos = Buffer; + ps->End = Buffer + PRINT_STRING_LEN - 1; + ps->Item = &Item; + + ps->fmt.Index = 0; + while ((c = PGETC(&ps->fmt))) { + + if (c != '%') { + PPUTC ( ps, c ); + continue; + } + + // setup for new item + Item.FieldWidth = (UINTN) -1; + Item.Width = 0; + Item.WidthParse = &Item.Width; + Item.Pad = ' '; + Item.PadBefore = TRUE; + Item.Comma = FALSE; + Item.Long = FALSE; + Item.Item.Ascii = FALSE; + Item.Item.pw = NULL; + ps->RestoreAttr = 0; + Attr = 0; + + while ((c = PGETC(&ps->fmt))) { + + switch (c) { + + case '%': + // + // %% -> % + // + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = '%'; + Item.Item.pw[1] = 0; + break; + + case '0': + Item.Pad = '0'; + break; + + case '-': + Item.PadBefore = FALSE; + break; + + case ',': + Item.Comma = TRUE; + break; + + case '.': + Item.WidthParse = &Item.FieldWidth; + break; + + case '*': + *Item.WidthParse = va_arg(ps->args, UINTN); + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *Item.WidthParse = 0; + do { + *Item.WidthParse = *Item.WidthParse * 10 + c - '0'; + c = PGETC(&ps->fmt); + } while (c >= '0' && c <= '9') ; + ps->fmt.Index -= 1; + break; + + case 'a': + Item.Item.pc = va_arg(ps->args, CHAR8 *); + Item.Item.Ascii = TRUE; + if (!Item.Item.pc) { + Item.Item.pc = (CHAR8 *)"(null)"; + } + break; + + case 's': + Item.Item.pw = va_arg(ps->args, CHAR16 *); + if (!Item.Item.pw) { + Item.Item.pw = L"(null)"; + } + break; + + case 'c': + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = (CHAR16) va_arg(ps->args, UINTN); + Item.Item.pw[1] = 0; + break; + + case 'l': + Item.Long = TRUE; + break; + + case 'X': + Item.Width = Item.Long ? 16 : 8; + Item.Pad = '0'; + case 'x': + Item.Item.pw = Item.Scratch; + ValueToHex ( + Item.Item.pw, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + + break; + + + case 'g': + Item.Item.pw = Item.Scratch; + GuidToString (Item.Item.pw, va_arg(ps->args, EFI_GUID *)); + break; + + case 'd': + Item.Item.pw = Item.Scratch; + ValueToString ( + Item.Item.pw, + Item.Comma, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + break + ; + case 't': + Item.Item.pw = Item.Scratch; + TimeToString (Item.Item.pw, va_arg(ps->args, EFI_TIME *)); + break; + + case 'r': + Item.Item.pw = Item.Scratch; + StatusToString (Item.Item.pw, va_arg(ps->args, EFI_STATUS)); + break; + + case 'n': + PSETATTR(ps, ps->AttrNorm); + break; + + case 'h': + PSETATTR(ps, ps->AttrHighlight); + break; + + case 'e': + PSETATTR(ps, ps->AttrError); + break; + + case 'N': + Attr = ps->AttrNorm; + break; + + case 'H': + Attr = ps->AttrHighlight; + break; + + case 'E': + Attr = ps->AttrError; + break; + + default: + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = '?'; + Item.Item.pw[1] = 0; + break; + } + + // if we have an Item + if (Item.Item.pw) { + PITEM (ps); + break; + } + + // if we have an Attr set + if (Attr) { + PSETATTR(ps, Attr); + ps->RestoreAttr = 0; + break; + } + } + + if (ps->RestoreAttr) { + PSETATTR(ps, ps->RestoreAttr); + } + } + + // Flush buffer + PFLUSH (ps); + return ps->Len; +} + +STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'}; + +VOID +ValueToHex ( + IN CHAR16 *Buffer, + IN UINT64 v + ) +{ + CHAR8 str[30], *p1; + CHAR16 *p2; + + if (!v) { + Buffer[0] = '0'; + Buffer[1] = 0; + return ; + } + + p1 = str; + p2 = Buffer; + + while (v) { + *(p1++) = Hex[v & 0xf]; + v = RShiftU64 (v, 4); + } + + while (p1 != str) { + *(p2++) = *(--p1); + } + *p2 = 0; +} + + +VOID +ValueToString ( + IN CHAR16 *Buffer, + IN BOOLEAN Comma, + IN INT64 v + ) +{ + STATIC CHAR8 ca[] = { 3, 1, 2 }; + CHAR8 str[40], *p1; + CHAR16 *p2; + UINTN c, r; + + if (!v) { + Buffer[0] = '0'; + Buffer[1] = 0; + return ; + } + + p1 = str; + p2 = Buffer; + + if (v < 0) { + *(p2++) = '-'; + v = -v; + } + + while (v) { + v = (INT64)DivU64x32 ((UINT64)v, 10, &r); + *(p1++) = (CHAR8)r + '0'; + } + + c = (Comma ? ca[(p1 - str) % 3] : 999) + 1; + while (p1 != str) { + + c -= 1; + if (!c) { + *(p2++) = ','; + c = 3; + } + + *(p2++) = *(--p1); + } + *p2 = 0; +} + +VOID +TimeToString ( + OUT CHAR16 *Buffer, + IN EFI_TIME *Time + ) +{ + UINTN Hour, Year; + CHAR16 AmPm; + + AmPm = 'a'; + Hour = Time->Hour; + if (Time->Hour == 0) { + Hour = 12; + } else if (Time->Hour >= 12) { + AmPm = 'p'; + if (Time->Hour >= 13) { + Hour -= 12; + } + } + + Year = Time->Year % 100; + + // bugbug: for now just print it any old way + SPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c", + Time->Month, + Time->Day, + Year, + Hour, + Time->Minute, + AmPm + ); +} + + + + +VOID +DumpHex ( + IN UINTN Indent, + IN UINTN Offset, + IN UINTN DataSize, + IN VOID *UserData + ) +{ + CHAR8 *Data, Val[50], Str[20], c; + UINTN Size, Index; + + UINTN ScreenCount; + UINTN TempColumn; + UINTN ScreenSize; + CHAR16 ReturnStr[1]; + + + uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize); + ScreenCount = 0; + ScreenSize -= 2; + + Data = UserData; + while (DataSize) { + Size = 16; + if (Size > DataSize) { + Size = DataSize; + } + + for (Index=0; Index < Size; Index += 1) { + c = Data[Index]; + Val[Index*3+0] = Hex[c>>4]; + Val[Index*3+1] = Hex[c&0xF]; + Val[Index*3+2] = (Index == 7)?'-':' '; + Str[Index] = (c < ' ' || c > 'z') ? '.' : c; + } + + Val[Index*3] = 0; + Str[Index] = 0; + Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str); + + Data += Size; + Offset += Size; + DataSize -= Size; + + ScreenCount++; + if (ScreenCount >= ScreenSize && ScreenSize != 0) { + // + // If ScreenSize == 0 we have the console redirected so don't + // block updates + // + ScreenCount = 0; + Print (L"Press Enter to continue :"); + Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16)); + Print (L"\n"); + } + + } +} |