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