]> git.proxmox.com Git - efi-boot-shim.git/blame - lib/console.c
New upstream version 15.5
[efi-boot-shim.git] / lib / console.c
CommitLineData
031e5cce 1// SPDX-License-Identifier: BSD-2-Clause-Patent
17857eb8
MG
2/*
3 * Copyright 2012 <James.Bottomley@HansenPartnership.com>
417077f8 4 * Copyright 2013 Red Hat Inc. <pjones@redhat.com>
17857eb8 5 */
f892ac66 6#include "shim.h"
29d9c7c3 7
f892ac66 8static UINT8 console_text_mode = 0;
17857eb8
MG
9
10static int
11count_lines(CHAR16 *str_arr[])
12{
13 int i = 0;
14
15 while (str_arr[i])
16 i++;
17 return i;
18}
19
20static void
21SetMem16(CHAR16 *dst, UINT32 n, CHAR16 c)
22{
d3819813 23 unsigned int i;
17857eb8
MG
24
25 for (i = 0; i < n/2; i++) {
26 dst[i] = c;
27 }
28}
29
dcc52381
GCPL
30EFI_STATUS
31console_get_keystroke(EFI_INPUT_KEY *key)
17857eb8 32{
f892ac66 33 SIMPLE_INPUT_INTERFACE *ci = ST->ConIn;
17857eb8 34 UINTN EventIndex;
f892ac66 35 EFI_STATUS efi_status;
17857eb8 36
8529e0f7
SM
37 if (!ci)
38 return EFI_UNSUPPORTED;
39
dcc52381 40 do {
8529e0f7 41 BS->WaitForEvent(1, &ci->WaitForKey, &EventIndex);
f892ac66
MTL
42 efi_status = ci->ReadKeyStroke(ci, key);
43 } while (efi_status == EFI_NOT_READY);
44
45 return efi_status;
46}
47
48static VOID setup_console (int text)
49{
50 EFI_STATUS efi_status;
51 EFI_CONSOLE_CONTROL_PROTOCOL *concon;
52 static EFI_CONSOLE_CONTROL_SCREEN_MODE mode =
53 EfiConsoleControlScreenGraphics;
54 EFI_CONSOLE_CONTROL_SCREEN_MODE new_mode;
55
56 efi_status = LibLocateProtocol(&EFI_CONSOLE_CONTROL_GUID,
57 (VOID **)&concon);
58 if (EFI_ERROR(efi_status))
59 return;
60
61 if (text) {
62 new_mode = EfiConsoleControlScreenText;
63
64 efi_status = concon->GetMode(concon, &mode, 0, 0);
65 /* If that didn't work, assume it's graphics */
66 if (EFI_ERROR(efi_status))
67 mode = EfiConsoleControlScreenGraphics;
68 if (text < 0) {
69 if (mode == EfiConsoleControlScreenGraphics)
70 console_text_mode = 0;
71 else
72 console_text_mode = 1;
73 return;
74 }
75 } else {
76 new_mode = mode;
77 }
78
79 concon->SetMode(concon, new_mode);
80 console_text_mode = text;
81}
82
83VOID console_fini(VOID)
84{
85 if (console_text_mode)
86 setup_console(0);
87}
88
031e5cce 89UINTN EFIAPI
f892ac66
MTL
90console_print(const CHAR16 *fmt, ...)
91{
031e5cce 92 ms_va_list args;
f892ac66
MTL
93 UINTN ret;
94
95 if (!console_text_mode)
96 setup_console(1);
97
031e5cce 98 ms_va_start(args, fmt);
f892ac66 99 ret = VPrint(fmt, args);
031e5cce 100 ms_va_end(args);
f892ac66
MTL
101
102 return ret;
103}
104
031e5cce 105UINTN EFIAPI
f892ac66
MTL
106console_print_at(UINTN col, UINTN row, const CHAR16 *fmt, ...)
107{
108 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
031e5cce 109 ms_va_list args;
f892ac66
MTL
110 UINTN ret;
111
112 if (!console_text_mode)
113 setup_console(1);
17857eb8 114
8529e0f7
SM
115 if (co)
116 co->SetCursorPosition(co, col, row);
f892ac66 117
031e5cce 118 ms_va_start(args, fmt);
f892ac66 119 ret = VPrint(fmt, args);
031e5cce 120 ms_va_end(args);
f892ac66
MTL
121
122 return ret;
17857eb8
MG
123}
124
f892ac66 125
17857eb8 126void
d3819813
MTL
127console_print_box_at(CHAR16 *str_arr[], int highlight,
128 int start_col, int start_row,
129 int size_cols, int size_rows,
130 int offset, int lines)
17857eb8
MG
131{
132 int i;
133 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
134 UINTN rows, cols;
135 CHAR16 *Line;
136
137 if (lines == 0)
138 return;
139
f892ac66
MTL
140 if (!console_text_mode)
141 setup_console(1);
142
8529e0f7
SM
143 if (!co)
144 return;
145
f892ac66 146 co->QueryMode(co, co->Mode->Mode, &cols, &rows);
17857eb8
MG
147
148 /* last row on screen is unusable without scrolling, so ignore it */
149 rows--;
150
151 if (size_rows < 0)
152 size_rows = rows + size_rows + 1;
153 if (size_cols < 0)
154 size_cols = cols + size_cols + 1;
155
156 if (start_col < 0)
157 start_col = (cols + start_col + 2)/2;
158 if (start_row < 0)
159 start_row = (rows + start_row + 2)/2;
160 if (start_col < 0)
161 start_col = 0;
162 if (start_row < 0)
163 start_row = 0;
164
d3819813 165 if (start_col > (int)cols || start_row > (int)rows) {
f892ac66
MTL
166 console_print(L"Starting Position (%d,%d) is off screen\n",
167 start_col, start_row);
17857eb8
MG
168 return;
169 }
d3819813 170 if (size_cols + start_col > (int)cols)
17857eb8 171 size_cols = cols - start_col;
d3819813 172 if (size_rows + start_row > (int)rows)
17857eb8 173 size_rows = rows - start_row;
d3819813 174
17857eb8
MG
175 if (lines > size_rows - 2)
176 lines = size_rows - 2;
177
178 Line = AllocatePool((size_cols+1)*sizeof(CHAR16));
179 if (!Line) {
f892ac66 180 console_print(L"Failed Allocation\n");
17857eb8
MG
181 return;
182 }
183
184 SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
185
186 Line[0] = BOXDRAW_DOWN_RIGHT;
187 Line[size_cols - 1] = BOXDRAW_DOWN_LEFT;
188 Line[size_cols] = L'\0';
f892ac66
MTL
189 co->SetCursorPosition(co, start_col, start_row);
190 co->OutputString(co, Line);
17857eb8
MG
191
192 int start;
193 if (offset == 0)
194 /* middle */
195 start = (size_rows - lines)/2 + start_row + offset;
196 else if (offset < 0)
197 /* from bottom */
198 start = start_row + size_rows - lines + offset - 1;
199 else
200 /* from top */
201 start = start_row + offset;
17857eb8
MG
202
203 for (i = start_row + 1; i < size_rows + start_row - 1; i++) {
204 int line = i - start;
205
206 SetMem16 (Line, size_cols*2, L' ');
207 Line[0] = BOXDRAW_VERTICAL;
208 Line[size_cols - 1] = BOXDRAW_VERTICAL;
209 Line[size_cols] = L'\0';
210 if (line >= 0 && line < lines) {
211 CHAR16 *s = str_arr[line];
212 int len = StrLen(s);
213 int col = (size_cols - 2 - len)/2;
214
215 if (col < 0)
216 col = 0;
217
031e5cce 218 CopyMem(Line + col + 1, s, MIN(len, size_cols - 2)*2);
17857eb8 219 }
d3819813 220 if (line >= 0 && line == highlight)
f892ac66
MTL
221 co->SetAttribute(co, EFI_LIGHTGRAY |
222 EFI_BACKGROUND_BLACK);
223 co->SetCursorPosition(co, start_col, i);
224 co->OutputString(co, Line);
d3819813 225 if (line >= 0 && line == highlight)
f892ac66
MTL
226 co->SetAttribute(co, EFI_LIGHTGRAY |
227 EFI_BACKGROUND_BLUE);
17857eb8
MG
228
229 }
230 SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
231 Line[0] = BOXDRAW_UP_RIGHT;
232 Line[size_cols - 1] = BOXDRAW_UP_LEFT;
233 Line[size_cols] = L'\0';
f892ac66
MTL
234 co->SetCursorPosition(co, start_col, i);
235 co->OutputString(co, Line);
17857eb8
MG
236
237 FreePool (Line);
238
239}
240
241void
242console_print_box(CHAR16 *str_arr[], int highlight)
243{
244 SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
245 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
dcc52381
GCPL
246 EFI_INPUT_KEY key;
247
f892ac66
MTL
248 if (!console_text_mode)
249 setup_console(1);
250
8529e0f7
SM
251 if (!co)
252 return;
253
17857eb8 254 CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
f892ac66
MTL
255 co->EnableCursor(co, FALSE);
256 co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
17857eb8
MG
257
258 console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0,
259 count_lines(str_arr));
260
dcc52381 261 console_get_keystroke(&key);
17857eb8 262
f892ac66
MTL
263 co->EnableCursor(co, SavedConsoleMode.CursorVisible);
264 co->SetCursorPosition(co, SavedConsoleMode.CursorColumn,
265 SavedConsoleMode.CursorRow);
266 co->SetAttribute(co, SavedConsoleMode.Attribute);
17857eb8
MG
267}
268
269int
d3819813 270console_select(CHAR16 *title[], CHAR16* selectors[], unsigned int start)
17857eb8
MG
271{
272 SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
273 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
274 EFI_INPUT_KEY k;
f892ac66 275 EFI_STATUS efi_status;
17857eb8 276 int selector;
d3819813 277 unsigned int selector_lines = count_lines(selectors);
17857eb8 278 int selector_max_cols = 0;
d3819813
MTL
279 unsigned int i;
280 int offs_col, offs_row, size_cols, size_rows, lines;
281 unsigned int selector_offset;
17857eb8
MG
282 UINTN cols, rows;
283
f892ac66
MTL
284 if (!console_text_mode)
285 setup_console(1);
286
8529e0f7
SM
287 if (!co)
288 return -1;
289
f892ac66 290 co->QueryMode(co, co->Mode->Mode, &cols, &rows);
17857eb8
MG
291
292 for (i = 0; i < selector_lines; i++) {
293 int len = StrLen(selectors[i]);
294
295 if (len > selector_max_cols)
296 selector_max_cols = len;
297 }
298
17857eb8
MG
299 if (start >= selector_lines)
300 start = selector_lines - 1;
301
302 offs_col = - selector_max_cols - 4;
303 size_cols = selector_max_cols + 4;
304
305 if (selector_lines > rows - 10) {
306 int title_lines = count_lines(title);
307 offs_row = title_lines + 1;
308 size_rows = rows - 3 - title_lines;
309 lines = size_rows - 2;
310 } else {
311 offs_row = - selector_lines - 4;
312 size_rows = selector_lines + 2;
313 lines = selector_lines;
314 }
315
d3819813 316 if (start > (unsigned)lines) {
17857eb8
MG
317 selector = lines;
318 selector_offset = start - lines;
319 } else {
320 selector = start;
321 selector_offset = 0;
322 }
323
324 CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
f892ac66
MTL
325 co->EnableCursor(co, FALSE);
326 co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
17857eb8
MG
327
328 console_print_box_at(title, -1, 0, 0, -1, -1, 1, count_lines(title));
329
330 console_print_box_at(selectors, selector, offs_col, offs_row,
331 size_cols, size_rows, 0, lines);
332
333 do {
f892ac66
MTL
334 efi_status = console_get_keystroke(&k);
335 if (EFI_ERROR (efi_status)) {
336 console_print(L"Failed to read the keystroke: %r",
337 efi_status);
dcc52381
GCPL
338 selector = -1;
339 break;
340 }
17857eb8
MG
341
342 if (k.ScanCode == SCAN_ESC) {
343 selector = -1;
344 break;
345 }
346
347 if (k.ScanCode == SCAN_UP) {
348 if (selector > 0)
349 selector--;
350 else if (selector_offset > 0)
351 selector_offset--;
352 } else if (k.ScanCode == SCAN_DOWN) {
353 if (selector < lines - 1)
354 selector++;
355 else if (selector_offset < (selector_lines - lines))
356 selector_offset++;
357 }
358
359 console_print_box_at(&selectors[selector_offset], selector,
360 offs_col, offs_row,
361 size_cols, size_rows, 0, lines);
362 } while (!(k.ScanCode == SCAN_NULL
363 && k.UnicodeChar == CHAR_CARRIAGE_RETURN));
364
f892ac66
MTL
365 co->EnableCursor(co, SavedConsoleMode.CursorVisible);
366 co->SetCursorPosition(co, SavedConsoleMode.CursorColumn,
367 SavedConsoleMode.CursorRow);
368 co->SetAttribute(co, SavedConsoleMode.Attribute);
17857eb8
MG
369
370 if (selector < 0)
371 /* ESC pressed */
372 return selector;
373 return selector + selector_offset;
374}
375
376
377int
378console_yes_no(CHAR16 *str_arr[])
379{
f892ac66
MTL
380 CHAR16 *yes_no[] = { L"No", L"Yes", NULL };
381 return console_select(str_arr, yes_no, 0);
17857eb8
MG
382}
383
384void
385console_alertbox(CHAR16 **title)
386{
f892ac66
MTL
387 CHAR16 *okay[] = { L"OK", NULL };
388 console_select(title, okay, 0);
17857eb8
MG
389}
390
391void
392console_errorbox(CHAR16 *err)
393{
394 CHAR16 **err_arr = (CHAR16 *[]){
395 L"ERROR",
396 L"",
397 0,
398 0,
399 };
400
401 err_arr[2] = err;
402
51d5bbcb 403 console_alertbox(err_arr);
17857eb8
MG
404}
405
406void
407console_notify(CHAR16 *string)
408{
409 CHAR16 **str_arr = (CHAR16 *[]){
410 0,
411 0,
412 };
413
414 str_arr[0] = string;
415
51d5bbcb 416 console_alertbox(str_arr);
17857eb8
MG
417}
418
031e5cce
SM
419void
420console_save_and_set_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
421{
422 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
423
424 if (!SavedMode) {
425 console_print(L"Invalid parameter: SavedMode\n");
426 return;
427 }
428
8529e0f7
SM
429 if (!co)
430 return;
431
031e5cce
SM
432 CopyMem(SavedMode, co->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
433 co->EnableCursor(co, FALSE);
434 co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
435}
436
437void
438console_restore_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
439{
440 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
441
8529e0f7
SM
442 if (!co)
443 return;
444
031e5cce
SM
445 co->EnableCursor(co, SavedMode->CursorVisible);
446 co->SetCursorPosition(co, SavedMode->CursorColumn,
447 SavedMode->CursorRow);
448 co->SetAttribute(co, SavedMode->Attribute);
449}
450
451int
452console_countdown(CHAR16* title, const CHAR16* message, int timeout)
453{
454 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
455 SIMPLE_INPUT_INTERFACE *ci = ST->ConIn;
456 SIMPLE_TEXT_OUTPUT_MODE SavedMode;
457 EFI_INPUT_KEY key;
458 EFI_STATUS efi_status;
459 UINTN cols, rows;
460 CHAR16 *titles[2];
461 int wait = 10000000;
462
8529e0f7
SM
463 if (!co || !ci)
464 return -1;
465
031e5cce
SM
466 console_save_and_set_mode(&SavedMode);
467
468 titles[0] = title;
469 titles[1] = NULL;
470
471 console_print_box_at(titles, -1, 0, 0, -1, -1, 1, 1);
472
473 co->QueryMode(co, co->Mode->Mode, &cols, &rows);
474
475 console_print_at((cols - StrLen(message)) / 2, rows / 2, message);
476 while (1) {
477 if (timeout > 1)
478 console_print_at(2, rows - 3,
479 L"Booting in %d seconds ",
480 timeout);
481 else if (timeout)
482 console_print_at(2, rows - 3,
483 L"Booting in %d second ",
484 timeout);
485
486 efi_status = WaitForSingleEvent(ci->WaitForKey, wait);
487 if (efi_status != EFI_TIMEOUT) {
488 /* Clear the key in the queue */
489 ci->ReadKeyStroke(ci, &key);
490 break;
491 }
492
493 timeout--;
494 if (!timeout)
495 break;
496 }
497
498 console_restore_mode(&SavedMode);
499
500 return timeout;
501}
502
503#define HORIZONTAL_MAX_OK 1920
504#define VERTICAL_MAX_OK 1080
505#define COLUMNS_MAX_OK 200
506#define ROWS_MAX_OK 100
507
508void
509console_mode_handle(VOID)
510{
511 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
512 EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
513 EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
514 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
515
516 UINTN mode_set;
517 UINTN rows = 0, columns = 0;
518 EFI_STATUS efi_status = EFI_SUCCESS;
519
8529e0f7
SM
520 if (!co)
521 return;
522
523 efi_status = BS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
031e5cce
SM
524 if (EFI_ERROR(efi_status)) {
525 console_error(L"Locate graphic output protocol fail", efi_status);
526 return;
527 }
528
529 Info = gop->Mode->Info;
530
531 /*
532 * Start verifying if we are in a resolution larger than Full HD
533 * (1920x1080). If we're not, assume we're in a good mode and do not
534 * try to change it.
535 */
536 if (Info->HorizontalResolution <= HORIZONTAL_MAX_OK &&
537 Info->VerticalResolution <= VERTICAL_MAX_OK) {
538 /* keep original mode and return */
539 return;
540 }
541
542 efi_status = co->QueryMode(co, co->Mode->Mode, &columns, &rows);
543 if (EFI_ERROR(efi_status)) {
544 console_error(L"Console query mode fail", efi_status);
545 return;
546 }
547
548 /*
549 * Verify current console output to check if the character columns and
550 * rows in a good mode.
551 */
552 if (columns <= COLUMNS_MAX_OK && rows <= ROWS_MAX_OK) {
553 /* keep original mode and return */
554 return;
555 }
556
557 if (!console_text_mode)
558 setup_console(1);
559
560 co->Reset(co, TRUE);
561
562 /*
563 * If we reached here, then we have a high resolution screen and the
564 * text too small. Try to switch to a better mode. Mode number 2 is
565 * first non standard mode, which is provided by the device
566 * manufacturer, so it should be a good mode.
567 */
568 if (co->Mode->MaxMode > 2)
569 mode_set = 2;
570 else
571 mode_set = 0;
572
573 efi_status = co->SetMode(co, mode_set);
574 if (EFI_ERROR(efi_status) && mode_set != 0) {
575 /*
576 * Set to 0 mode which is required that all output devices
577 * support at least 80x25 text mode.
578 */
579 mode_set = 0;
580 efi_status = co->SetMode(co, mode_set);
581 }
582
8529e0f7 583 clear_screen();
031e5cce
SM
584
585 if (EFI_ERROR(efi_status)) {
586 console_error(L"Console set mode fail", efi_status);
587 }
588
589 return;
590}
17857eb8
MG
591
592/* Copy of gnu-efi-3.0 with the added secure boot strings */
593static struct {
594 EFI_STATUS Code;
031e5cce 595 CHAR16 *Desc;
17857eb8
MG
596} error_table[] = {
597 { EFI_SUCCESS, L"Success"},
598 { EFI_LOAD_ERROR, L"Load Error"},
599 { EFI_INVALID_PARAMETER, L"Invalid Parameter"},
600 { EFI_UNSUPPORTED, L"Unsupported"},
601 { EFI_BAD_BUFFER_SIZE, L"Bad Buffer Size"},
602 { EFI_BUFFER_TOO_SMALL, L"Buffer Too Small"},
603 { EFI_NOT_READY, L"Not Ready"},
604 { EFI_DEVICE_ERROR, L"Device Error"},
605 { EFI_WRITE_PROTECTED, L"Write Protected"},
606 { EFI_OUT_OF_RESOURCES, L"Out of Resources"},
607 { EFI_VOLUME_CORRUPTED, L"Volume Corrupt"},
608 { EFI_VOLUME_FULL, L"Volume Full"},
609 { EFI_NO_MEDIA, L"No Media"},
610 { EFI_MEDIA_CHANGED, L"Media changed"},
611 { EFI_NOT_FOUND, L"Not Found"},
612 { EFI_ACCESS_DENIED, L"Access Denied"},
613 { EFI_NO_RESPONSE, L"No Response"},
614 { EFI_NO_MAPPING, L"No mapping"},
615 { EFI_TIMEOUT, L"Time out"},
616 { EFI_NOT_STARTED, L"Not started"},
617 { EFI_ALREADY_STARTED, L"Already started"},
618 { EFI_ABORTED, L"Aborted"},
619 { EFI_ICMP_ERROR, L"ICMP Error"},
620 { EFI_TFTP_ERROR, L"TFTP Error"},
621 { EFI_PROTOCOL_ERROR, L"Protocol Error"},
622 { EFI_INCOMPATIBLE_VERSION, L"Incompatible Version"},
623 { EFI_SECURITY_VIOLATION, L"Security Violation"},
624
625 // warnings
031e5cce 626 { EFI_WARN_UNKNOWN_GLYPH, L"Warning Unknown Glyph"},
17857eb8
MG
627 { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"},
628 { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"},
629 { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"},
630 { 0, NULL}
631} ;
632
633
634static CHAR16 *
635err_string (
f892ac66 636 IN EFI_STATUS efi_status
17857eb8
MG
637 )
638{
639 UINTN Index;
640
641 for (Index = 0; error_table[Index].Desc; Index +=1) {
f892ac66 642 if (error_table[Index].Code == efi_status) {
17857eb8
MG
643 return error_table[Index].Desc;
644 }
645 }
646
647 return L"";
648}
17857eb8
MG
649
650void
f892ac66 651console_error(CHAR16 *err, EFI_STATUS efi_status)
17857eb8
MG
652{
653 CHAR16 **err_arr = (CHAR16 *[]){
654 L"ERROR",
655 L"",
656 0,
657 0,
658 };
659 CHAR16 str[512];
660
f892ac66
MTL
661 SPrint(str, sizeof(str), L"%s: (0x%x) %s", err, efi_status,
662 err_string(efi_status));
17857eb8
MG
663
664 err_arr[2] = str;
665
51d5bbcb 666 console_alertbox(err_arr);
17857eb8
MG
667}
668
669void
670console_reset(void)
671{
672 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
673
f892ac66
MTL
674 if (!console_text_mode)
675 setup_console(1);
676
8529e0f7
SM
677 if (!co)
678 return;
679
f892ac66 680 co->Reset(co, TRUE);
17857eb8 681 /* set mode 0 - required to be 80x25 */
f892ac66
MTL
682 co->SetMode(co, 0);
683 co->ClearScreen(co);
17857eb8 684}
417077f8 685
8529e0f7
SM
686void
687clear_screen(void)
688{
689 SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
690
691 if (!co)
692 return;
693
694 co->ClearScreen(co);
695}
4ab978a3
PJ
696
697VOID
698setup_verbosity(VOID)
699{
f892ac66
MTL
700 EFI_STATUS efi_status;
701 UINT8 *verbose_check_ptr = NULL;
4ab978a3
PJ
702 UINTN verbose_check_size;
703
f892ac66
MTL
704 verbose_check_size = sizeof(verbose);
705 efi_status = get_variable(L"SHIM_VERBOSE", &verbose_check_ptr,
706 &verbose_check_size, SHIM_LOCK_GUID);
707 if (!EFI_ERROR(efi_status)) {
708 verbose = *(__typeof__(verbose) *)verbose_check_ptr;
709 verbose &= (1ULL << (8 * verbose_check_size)) - 1ULL;
710 FreePool(verbose_check_ptr);
417077f8
PJ
711 }
712
f892ac66 713 setup_console(-1);
417077f8 714}
b6f94dbe 715
b6f94dbe
MTL
716VOID
717msleep(unsigned long msecs)
718{
8529e0f7 719 BS->Stall(msecs);
b6f94dbe 720}
f892ac66
MTL
721
722/* This is used in various things to determine if we should print to the
723 * console */
724UINT8 in_protocol = 0;